在无序数组中找到大小为3的任何增加子序列

时间:2015-07-29 14:12:23

标签: arrays algorithm

我在线遇到了一个问题:使用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

我想知道这个还有其他解决方案吗?

2 个答案:

答案 0 :(得分:0)

您是否尝试过查看cs.stackexchange?

它已在那里得到解决:https://cs.stackexchange.com/questions/1071/is-there-an-algorithm-which-finds-sorted-subsequences-of-size-three-in-on-ti

一个想法是做一些像增长最长的子序列算法,并在一次通过中做。

我在这个问题上有多种解决方案。

答案 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;
}