时间复杂度O(n)如何?

时间:2018-01-28 17:43:55

标签: c++ algorithm

我正在尝试从LeetCode.com解决以下问题:

  

根据每日温度列表,生成一个列表,对于输入中的每一天,它会告诉您在温度较高的情况下需要等待多少天。如果没有可能的未来日期,请改为0。如果输入为:[73, 74, 75, 71, 69, 72, 76, 73],则输出应为:[1, 1, 4, 2, 1, 1, 0, 0]

工作代码如下:

class Solution {
public:

    vector<int> dailyTemperatures(vector<int>& temperatures) {
        stack<int> s;
        vector<int> result(temperatures.size(),0);

        for(int i=0; i<(int)temperatures.size(); i++) {
            while(!s.empty() && temperatures[i]>temperatures[s.top()]) {
                int idx = s.top();
                s.pop();
                result[idx] = i-idx;
            }
            s.push(i);
        }

        return result;
    }
};

根据solutions,上述代码段的时间复杂度为O(n)。怎么样?如果我们考虑最坏情况输入:[75, 71, 69, 72, 76],那么时间复杂度就不会是O(n ^ 2),因为我们会将几乎所有元素插入到堆栈中s然后在我们遇到76时将它们全部弹出?基本上,因为,如果我理解正确,我们两次访问几乎所有元素?

有人可以解释一下吗?感谢。

编辑:看起来像我的陈述_&#34;我们两次访问几乎所有元素&#34; _暗示意思不正确。我知道O(n+n)O(n^2)之间的区别。在这里,我认为它应该是O(n^2),因为对于给定的ii=4),我们pop()堆栈中的所有元素,在最坏的情况下。

2 个答案:

答案 0 :(得分:1)

问题是温度介于[30,100]之间。 因此,generate-selectors不会超过71。 然后我们可以假设一个循环有不断的迭代。 只有一个会“计数”,所以,O(n)。

通过常量循环,它永远不会显示多项式行为。

答案 1 :(得分:0)

只有O(n),因为......

  

在这里,我认为它应该是O(n ^ 2),因为对于给定的i(i = 4),我们在最坏的情况下pop()堆栈中的所有元素。

虽然对于i = 4这是正确的,但是整个运行中堆栈的pop“粘住”(影响堆栈内容),它不是“每i”,并且整个运行只有N个元素一直被推到堆栈中,因此最多可以弹出N个元素(不能弹出没有被推入的元素)。在您的情况下,i = {0, .., 3}“挨饿” - 只是未通过pop测试 - 仅执行push操作,保存了足够的操作来证明i=4 pop的合理性操作混乱,使其仍然是O(N)的总和。

特定i是否从堆栈中弹出没有元素,一个元素,两个元素或N个元素并不重要,因为它只会使剩余的工作量(堆栈的剩余内容)更大/更小对于剩余的i值,在任何情况下总计最多N次pop次操作。因此,它不是NxN,而是N + N.

如果堆栈对于每个i是独立的,并且有一些机会为每个i增长到N-ish大小,那么它将是NxN,那么这将是O(N 2 ),但事实并非如此。