如何解决找到一维的最短路径
| 在一维数组S中,可能有任意数量的元素属于该集合U:{A,B,C,D,E}
并允许重复。
范例:
S = {E,A,E,C}
问题是:
在任何给定数组S中,确定包含属于集合U的所有元素的最短范围/路径的最有效方法是什么?请记住,数组无法排序。
在上面的示例中,最短路径是连接数组S的前5个元素的路径。
编辑:
1)集U的元素数不是恒定的。
提前致谢。
解决方法
有趣的作业,但是您仍然必须自己编写代码。
好消息是您没有告诉我们您使用哪种语言,因此当您决定自己编写代码时,我以它为标志,这很好。
到目前为止,我最好的尝试:
有2个用于子字符串(范围)的指针,一个用于范围的开始(较小的索引),而一个用于结束(较大的索引)的指针。两者都首先指向数组的开头。
分别列出范围内的ABCDE数量。
从左到右迭代结束。
对于每个字符,增加列表中该字符的编号。如果结果(增加了多少)> 1(请看起始点是否指向同一个字符。如果是,则向前移动起始字符并减去1,和),而起始指向与之相关的数字> 1的字符,向前移动起始字符和减1。
如果列表中的ABCDE全部> = 1,那么我们已经找到一个候选范围。将其与最短长度(如果有)进行比较,如果更短,则更新最短长度并记录新最短范围的开始索引。
,如果我对问题的理解正确,我认为您需要做(语言不可知)
int partLen <- U.length;
do {
Vector subSets <- S.partition(partLen);
foreach set I in subSets
if I.isEqualTo(U) then
return true;
else
partLen <- partLen + 1;
} while (partLen <= S.length);
return false;
partition
会将S分解为任何长度的子集
isEqualTo
可以正确比较集合。
,首先在数组中找到不同的元素,它们是O(n)的东西。然后使用滑动窗口方法找到所有这些元素都存在的最小跨度。
您可以在此处查看如何找到最小窗口:http://tech-queries.blogspot.com/2010/12/finding-minimum-window-in-array-which.html
,这是一个简单的算法,它会扫描阵列一次,并不断检查其当前看到的覆盖范围是否比以前看到的覆盖范围短。
为简单起见,我假设我们可以将A,B,C,D和E映射到整数0-4,以便我们可以轻松地引用数组。我尚未对其进行彻底检查,因此请在思想上/实际上在一个或两个示例上运行它,以确保它能够满足您的要求。
//Cell 0 is the last index at which we saw an A,cell 1 \" \" saw a B,etc.
int[] mostRecent = new int[U.length];
mostRecent.setAllValsTo(POSITIVE_INFINITY);
int shortestRange = POSITIVE_INFINITY; //We are trying to minimize this number.
int minIndex = 0; //The beginning index of the range
int maxIndex = POSITIVE_INFINITY; //The ending index of the range.
for(int i=0; i< S.length; i++) {
int currentValue = S[i]; //This value will be 0-4,corresponding to A-E
mostRecent[currentValue] = i;
currentMax = mostRecent.findMax(); //beginning of current range
currentMin = mostRecent.findMin(); //end of current range
currentRange = currentMax - currentMin;
if(currentRange < shortestRange) {
shortestRange = currentRage;
minIndex = currentMin;
maxIndex = currentMax;
}
}
//currentMax and currentMin now carry the starting and ending indices,use them as you see fit.
return shortestRange;
这是O(nk)阶,其中n = S.length,k = U.length。仍然有很多优化方法可以解决,但我不知道我是否可以降低最坏情况的订单量。
,这是我的方法(用伪代码)
let counters[] be an array such that
counters[j] = number of occurrences of character j,where j = 0 for \'A\',j = 1 for \'B\',etc.
build counters[] by scanning the original string s
let positions[j][] be an array listing the positions occupied by
character j in the original string s; note the size of
positions[j][] is equal to counters[j]
build positions[j][] by scanning the original string s;
let currentPositions[] be an array such that
positions[j][currentPositions[j]] gives the position of the next
occurrence of character j in the original string s
initially currentPositions[j] = 0 for every j = [0 .. u.length]
let bestLength = s.length
let bestMin = 0
let bestMax = 0
for i in [0 .. s.length] {
for j in [0 .. u.length] {
if (
positions[i][currentPositions[i]] < i and
currentPositions[j] + 1 < counters[j]
)
currentPositions[j]++
}
let min = s.length
int max = 0
for j in [0 .. u.length] {
curPos = positions[j][currentPositions[j]
if (curPos > max) let max = curPos
if (curPos < min) let min = curPos
}
if (max - min + 1 < bestLength) {
let bestMin = min
let bestMax = max
let bestLength = max - min + 1
}
}
the shortest path is that starting at bestMin,ending at bestMax,and having length bestLength
复杂度为O(nk),其中n = s.length,k = u.length
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。