我在线遇到了一个问题:使用O(n)时间复杂度在无序数组中找到大小为3的任何增加子序列。 (只需要返回一个有效的结果)
For example:
1 2 0 3 ==> 1 2 3
2 4 7 8 ==> 2 4 7; 4 7 8; 2 4 8 (anyone of them is Okay)
这个与最长的增加子序列非常相关。但它也非常具体:我们只想要大小3.我找到了一个O(N)解决方案,它需要扫描两次数组。
The idea:
(1) For each element, find is there any one smaller than it on the left side, is there any one larger than it on the right side.
(2) We can compute a minimum pre-array and a maximum post-array as pre-processing. For example:
1 2 0 3 ==> minimum pre-array: none 1 1 0
1 2 0 3 ==> maximum post-array: 3 3 3 None
我想知道这个还有其他解决方案吗?
答案 0 :(得分:0)
您是否尝试过查看cs.stackexchange?
一个想法是做一些像增长最长的子序列算法,并在一次通过中做。
我在这个问题上有多种解决方案。
答案 1 :(得分:0)
这是问题引用的解决方案(在JavaScript中)
评论http://www.geeksforgeeks.org/find-a-sorted-subsequence-of-size-3-in-linear-time/还有其他替代解决方案。
function findIncSeq3(arr) {
var hi = Array(arr.length);
var lo = Array(arr.length);
hi[arr.length - 1] = lo[0] = null;
var tmp, i;
for (i = arr.length - 2, tmp = arr.length - 1; i >= 0; i--) {
if (arr[i] >= arr[tmp]) {
tmp = i;
hi[i] = null;
} else {
hi[i] = tmp;
}
}
for (i = 1, tmp = 0; i < arr.length; i++) {
if (arr[i] <= arr[tmp]) {
tmp = i;
lo[i] = null;
} else {
lo[i] = tmp;
}
}
for(i = 0; i < arr.length; i++) {
if(hi[i] !== null && lo[i] != null) {
return [arr[lo[i]], arr[i], arr[hi[i]]];
}
}
return null;
}
console.log("1,2,5", findIncSeq3([1, 2, 0, 5]));
console.log("null", findIncSeq3([5, 4, 3, 2, 1]));
console.log("2,3,9", findIncSeq3([10, 8, 6, 4, 2, 5, 3, 9]));
编辑这是一个单一的迭代版本。
function findIncSeq3(arr) {
var tmp = Array(arr.length);
for(var i = 0, s = arr.length - 1, lo = 0, hi = arr.length -1; i <= s; i++) {
if(s - i !== hi) {
if(arr[s - i] >= arr[hi]) {
hi = s - i;
} else if(tmp[s - i] !== undefined) {
return [arr[tmp[s - i]], arr[s - i], arr[hi]];
} else {
tmp[s - i] = hi;
}
}
if(i !== lo) {
if(arr[i] <= arr[lo]) {
lo = i;
} else if(tmp[i] !== undefined) {
return [arr[lo], arr[i], arr[tmp[i]]];
} else {
tmp[i] = lo;
}
}
}
return null;
}