最长的子序列 - 线性时间解?

时间:2014-05-01 16:23:29

标签: algorithm stack sequence lis

我们可以使用堆栈在迭代数组时继续记录增加的子序列。运行时间是线性的,因为每个元素进入和离开堆栈一次。

如果我们想输出实际的序列而不是它的长度,我们可以记录起始索引,然后找到更大值后面的所有元素。

这种线性时间算法有效吗?

    public int longestIncreasingSubsequence(int[] seq) {
    int longest = 0;
    int curSize = 0;

    LinkedList<Integer> stack = new LinkedList<Integer>();

    for (int i : seq) {
        while (!stack.isEmpty() && i <= stack.get(0)) {
            stack.removeFirst();
            curSize--;
        }
        stack.addFirst(i);
        curSize++;
        if (curSize > longest) {
            longest = curSize;
        }
    }

    return longest;
}

1 个答案:

答案 0 :(得分:1)

没有。您编写的算法不正确。

考虑测试用例:15,20,12,25

After two pushes:
stack: 20,15
curSize: 2
longest: 2

In comes 12. So two pops.
curSize: 0

12 pushed:
stack: 12
curSize: 1
longest: 2

25 pushed:
stack: 25,12
curSize: 2
longest: 2 //so gives answer 2

但实际上答案应该是3。