【问题标题】:Is this correct time complexity?这是正确的时间复杂度吗?
【发布时间】:2021-04-08 01:35:38
【问题描述】:

我这样做是为了解决其中一个 leetcode 问题,但我不确定我的算法的复杂性是什么。

public String countAndSay(int n) {
        if (n == 1) return "1";
        String pre = countAndSay(n-1);
        char[] prev = pre.toCharArray();
        int len = prev.length;
        if (len == 1 && prev[0] == '1') return "11";
        int idx = 1;
        int rep = 1;
        String res = "";
        while (idx <= len) {
            if (idx == len) {
                res += (Integer.toString(rep) + prev[idx-1]);
                break;
            }
            if (prev[idx-1] == prev[idx]) rep++;
            else {
                res += (Integer.toString(rep) + prev[idx-1]);
                rep = 1;
            }
            idx++;
        }
        return res;
    }

由于递归发生n次,循环是O(n),我觉得应该是O(n^2)。那是对的吗?如果不是,你能解释一下原因吗?

【问题讨论】:

  • 这不正确,因为您忘记考虑结果字符串的长度。在 big-O 中,它可能归类为 O(2^n)
  • @Andreas 假设字符串的长度是 m。为什么不是 O(mn)?
  • 该方法只有一个输入:n。没有m输入,所以公式不能基于m

标签: performance time time-complexity big-o code-complexity


【解决方案1】:

以下是一些事实:

  • 该方法在输入n-1 上递归调用自身。
  • 该方法生成称为look-and-say sequence 的序列。
  • 结果字符串的长度随着基数 λ 呈指数增长,其中 λ = 1.303577269034... 为Conway's constant,因此长度为O(λ^n)
  • 循环是字符串长度的二次方(因为重复的字符串连接),所以我们有O((λ^n)^2) = O((λ^2)^n) 用于循环。

因此我们可以推导出以下递归关系:

T(0) = 1
T(n) = T(n-1) + O((λ^2)^n)

这种关系的渐近行为由下式给出

T(n) ∈ Θ((λ^2)^n) = Θ(1.6993^n)

如果您使用StringBuilder 而不是进行邪恶的重复字符串连接,则可以将其降低到Θ(λ^n),这对于这个问题也是渐近最优的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    相关资源
    最近更新 更多