【问题标题】:How do determine Big-O of recursive code?如何确定递归代码的 Big-O?
【发布时间】:2016-10-18 06:12:30
【问题描述】:

我有以下代码,这是这个问题的答案:https://leetcode.com/problems/add-digits/

class Solution {
public:
    int addDigits(int num) {
        if (!num/10)
            return num;

        long d = 1;
        int retVal = 0;

        while(num / d){
            d *= 10;
        }
        for(d; d >= 1; d/=10){
            retVal += num / d;
            num %= d;
        }
        if (retVal > 9)
            retVal = addDigits(retVal);

        return retVal;
    }
};

不过,作为对此的后续行动,我正在尝试确定 BigO 的增长情况。我第一次尝试计算它是O(n^n)(我假设因为每个深度的增长都直接取决于每次n),这令人沮丧。我错了吗?我希望我错了。

【问题讨论】:

  • 当然不是O(n^n)。而是像O(f(n)) 这样的东西,其中f() 是一个非线性函数。我不太熟悉这个话题,所以很抱歉我不能告诉你f() 应该是什么样子。

标签: c++ recursion big-o


【解决方案1】:

在这种情况下,它是线性的 O(n),因为您递归地调用 addDigits 方法,没有任何循环,并且在方法主体中不会出现一次

更多详情: Determining complexity for recursive functions (Big O notation)

更新: 从递归函数被调用一次的角度来看,它是线性的。但是,在这种情况下,情况并不完全正确,因为执行次数几乎不取决于输入参数。

【讨论】:

  • 但它递归的数量与n不是线性的
【解决方案2】:

看起来它是 O(1) 用于值 O(n) 用于任何其他值。

我对 Big-O 表示法不够精通,无法给出如何组合的答案。

很可能第一部分在重要性上是可以接受的,因此整体时间复杂度变为O(n)

【讨论】:

    【解决方案3】:

    nnum 的以10 为底的位数。 我会这么说

    T(1)=O(1)

    T(n)=n+T(n') 与 n'

    这给了我们

    O(n*n)

    但是我们可以做得更好吗? 请注意,用 2 位数字表示的最大数字是 99,以这种方式减少 99->18->9

    请注意,我们总是可以将 10 个数字折叠成 2 个9999999999->90。对于n>10,我们可以将n/10segments 中的数字分解为每个最多10 位数字,并将这些段减少为每个2 位数字的数字相加。 n/10 2 位数的总和将始终小于(或等于)(n/10)*2 位数。因此

    T(n)=n+T(n/5) 对于 n>=10

    n

    T(n)=O(1) 对于 n

    T(n)=n+T(n/5) 对于 n>=10

    求解递推方程得到

    n>=10 的 O(n)

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多