【问题标题】:What is the Time Complexity for this solution of trimming a message of N length at M length?这种以 M 长度修剪 N 长度消息的解决方案的时间复杂度是多少?
【发布时间】:2020-07-18 16:53:42
【问题描述】:

我正在尝试为以下问题的解决方案获得正确的时间复杂度:

Input: a string contains spaces and words, and an integer M
Output: trim the string so the trimmed string length <= m and no cut-off word.
Sample:
S = "This is JavaScript", M = 10.
Expect: "This is" // because "This is Ja" is invalid, "JavaScript" is cut. 
S = "JavaScript", M = 5
Expect: "" // empty because the output "JavaS" is invalid.
S = "JavaScript", M = 10
Expect: "JavaScript"

这是我的代码:

function trimThis(S, M) {
    if (M > S.length) return S;
    let output = S.slice(); // Making a copy of the input is optional
    while (output.length > M) {
        const lastSpaceIdx = output.lastIndexOf(' ');
        if (lastSpaceIdx !== -1) {
            const endIdx = Math.min(lastSpaceIdx, output.length);
            output = output.slice(0, endIdx);
        }
        else return '';
    }
    // In JS we can also use trimEnd() to remove trailing spaces:
    while (output.length > 0 && output[output.length - 1] === ' ') {
        output = output.slice(0, -1);
    }
    return output;
}

我认为总时间复杂度是 O(N),其中 n = len(S),但由于 while 循环,我不确定。

while 循环将运行 O(N - M) 次。在每次迭代中,代码执行 O(N) 操作来查找最后一个空间索引,slice() 操作需要 O(N),所以它看起来像 O(N^2)。然而,在每次迭代之后,字符串变得越来越小。

复制字符串O(N)的时间不会影响整体大O。

【问题讨论】:

  • 请解释您的输入,正确输出。什么是截词?
  • 谢谢。我已更新问题以使其更清晰。

标签: javascript algorithm big-o


【解决方案1】:

时间复杂度为O(n²),因为您重复执行slice,每次都会创建一个新字符串。 slice的实现虽然很快,但在时间上不是恒定的,而是与长度成正比的。

您应该只使用索引,并在最后执行“昂贵的”slice。另请注意,不需要初始切片,因为字符串是不可变的。无法修改 S,即使您愿意。

这是您的代码,仅适用于最后执行 slice。注意:我不会为变量名使用首字母大写,因为通常是为构造函数的名称保留的。

function trimThis(s, m) {
    let endIdx = s.length;
    while (endIdx > m) {
        lastSpaceIdx = s.lastIndexOf(' ', endIdx - 1);
        if (lastSpaceIdx !== -1) {
            endIdx = lastSpaceIdx;
        } else return '';
    }
    while (endIdx > 0 && s[endIdx - 1] === ' ') {
        endIdx--;
    }
    return s.slice(0, endIdx);
}

let s = "We are living in interesting times";
let res = trimThis(s, 20);
console.log(res);

现在是O(n)

【讨论】:

  • “虽然 slice 的实现速度很快,但它在时间上不是恒定的,而是与它的长度成正比的。” 对于 V8 来说,这不再是正确的。 somemoreinfo
  • @Thomas,确实如此。不过,只要这不是 EcmaScript 要求的一部分,我们就不应该依赖它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-10
  • 2020-06-12
  • 1970-01-01
  • 2014-11-11
  • 2021-02-13
  • 2020-11-13
  • 1970-01-01
相关资源
最近更新 更多