【问题标题】:Is this function O(n^3)?这个函数是 O(n^3) 吗?
【发布时间】:2021-11-20 06:23:53
【问题描述】:

正在研究一个 leetcode 问题,并收到反馈说以下代码块的时间复杂度为 O(n^3)。有人可以帮我解释一下这是怎么回事吗?我数了两个循环,这让我相信这是 O(n^2)。

var longestPalindrome = function(s) {
    let maxString = "";
    let originalString = s;
    let reversedString = s.split("").reverse().join("");
    
    for (let i = 0; i < s.length; i++){
        for (let j = i+1; j < s.length+1; j++){
            if (i<j){
                let iteratedSubstring = originalString.substring(i,j)
                     if (reversedString.includes(iteratedSubstring) && (iteratedSubstring === iteratedSubstring.split("").reverse().join("")) ){
                     iteratedSubstring.length > maxString.length ? maxString =  iteratedSubstring: maxString = maxString
                 }
            }
        }
    }
    return maxString
}

【问题讨论】:

  • 拆分和反向都在O(n)中
  • iteratedSubstring.split("").reverse().join("")这样的操作在子串的长度上是O(n)。

标签: javascript algorithm big-o


【解决方案1】:

if 块执行了 O(?²) 次,但该块的主体不是 O(1):

  • originalString.substring(i,j) 可能具有 O(?−?) 时间复杂度(取决于实现),因此平均时间复杂度为 O(?)。另见:Is Javascript substring virtual?
  • reversedString.includes(iteratedSubstring) 的时间复杂度为 O(?)
  • iteratedSubstring.split("") 的时间复杂度为 O(?)
  • .reverse() 的时间复杂度为 O(?)
  • .join("") 的时间复杂度为 O(?)

因此,if 块的时间复杂度为 O(n) 有几个原因,总体时间复杂度为 O(?³)

【讨论】:

  • 在这个答案中也要注意,如果n最初是s的长度,那么整个答案中都不会这样使用。如果我们在复杂度为 O(m) 的循环中有一个复杂度为 O(n) 的函数,则结果将是 O(nm),它不等于 O(?²)。
  • @T.Trassoudaine,该算法只有一个输入大小:s 的大小。 iteratedSubstring 有自己的大小(即?−?)这一事实在第一个要点中有所说明:它平均也是 O(?),这就是为什么最后三个要点也可以提到 O(?)。所以我重申:O(?) always 中的 ? 指的是这个答案中 s 的长度。
  • 是的,但考虑到 O(nm),m
  • @T.Trassoudaine,计算的所有j-i 大小的总和由公式1(n-1)+2(n-2)+...+(n-1)1 给出,即n(n+1)n/2-n(n+1)(2n+1)/6,即O(n³)。所以这意味着substring(j-i)的单次执行的平均时间复杂度是O(n)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-10
  • 2020-11-29
相关资源
最近更新 更多