【问题标题】:Why is the time complexity of this code O(N)?为什么这段代码的时间复杂度是 O(N)?
【发布时间】:2023-04-07 13:05:01
【问题描述】:

我认为下面代码的时间复杂度是 O(n^2) 或 O(n*logn)。

int j = 0;

for(i = 0; i < n; ++i) {
    while(j < n && arr[i] < arr[j]) {
        j++;
    }
}

但是,答案页面显示它是 O(n)。
我不明白为什么会这样。
我的(愚蠢的)意见如下:

  1. 时间复杂度为 O(n^2),因为有两个循环运行n 次。 arr[i] &lt; arr[j] 可能会影响while 循环,但没关系。
  2. 时间复杂度为 O(n*logn),因为 while 循环可能运行少于 n 次,因为在循环期间 arr[j] 可能小于 arr[i]。因此,while 循环将运行log(n) 次。

你能解释一下为什么我的答案是错误的,为什么正确的时间复杂度是 O(n)?

【问题讨论】:

  • 请注意 j 较新的重置为 0。所以内部循环总共只能运行 O(n) 次
  • 内部循环将只运行一次,因为您没有将 j 重新初始化为 0。

标签: c++ c algorithm time-complexity complexity-theory


【解决方案1】:
for(i = 0; i < n; ++i)

循环n 次。

while(j < n && arr[i] < arr[j]) {
    j++;
}

循环高达n总共。请注意,j 只会在i 的整个循环中递增,因此它是一个内部循环并不会使其更高阶,因为它仍然只能从0n 整个一组循环。

所以它是O(2n) = O(n)

【讨论】:

  • 现在明白了...一旦 j 达到 n,它不会重置为 0,因此 while 循环将不再运行。
  • 是的,或者即使它永远不会到达n,它仍然永远不会重置,因此它永远不会超过n
【解决方案2】:

一般来说,要了解此类事情的流程,请尝试添加打印语句以了解流程,在每个点打印“i”和“j”。

在这种特定情况下,您知道外部for 循环被触发了多少次,但请尝试查看j 总共可以增加多少次。即使它在for 循环内,它的总迭代次数也可能是独立的。

【讨论】:

    猜你喜欢
    • 2018-12-12
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 2018-03-19
    • 2020-12-16
    相关资源
    最近更新 更多