【问题标题】:Longest Increasing Subsequence -- Linear Time Solution?最长递增子序列——线性时间解?
【发布时间】:2014-05-01 16:23:29
【问题描述】:

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

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

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

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

【问题讨论】:

  • 我试过了,它给出了正确的结果。但很难说它是否是 O(n)。维基百科和其他来源都将此问题标记为 O(nlogn)
  • 也许你把子串(连续)和子序列(不需要连续)混淆了
  • @NiklasB。这也不会给出最长的增加子字符串。
  • @RikayanBandyopadhyay 我认为是的。
  • @NiklasB。 1,2,3,8,4,5 呢?结果为 5。

标签: algorithm stack sequence lis


【解决方案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。

【讨论】:

  • But in reality the answer should be 3. - 怎么样?
  • @500-InternalServerError 15,20,25
  • 啊,我以为它必须是完整的。
  • @500-InternalServerError 子序列,不是子数组。
  • 好测试用例!我以为每一个递增的子序列都会进入堆栈,但事实并非如此。
猜你喜欢
  • 2013-07-03
  • 1970-01-01
  • 2020-04-15
  • 2013-10-28
  • 1970-01-01
  • 2018-11-01
相关资源
最近更新 更多