在计算时间复杂度时,“要考虑的操作”(例如,If,return,assign ..)

时间:2018-03-07 02:00:07

标签: algorithm recursion time-complexity big-o

我正在研究算法 - 时间复杂度和递归。 我实际上可以解决递归问题,因为这是简单的数学运算。但代码部分是问题所在。

例如,这是我带来的问题: https://brilliant.org/practice/big-o-notation/?problem=complexityrun-time-analysis-2-2

public int P(int x , int n){
    if (n == 0){
        return 1;
    }
    if (n % 2 == 1){
        int y = P(x, (n - 1) / 2);
        return x * y * y;
    }
    else{
        int y = P(x, n / 2);
        return y * y;               
    }
}

这是一个简单的电源功能。 T(n)= O(g(n))这个函数的运行时间很大,我必须找到它。

解决方案说, “当功率为奇数时,执行额外的乘法运算。为了计算时间复杂度,让我们首先看一下最糟糕的情况,这意味着让我们假设需要一个额外的乘法运算。“

但是,我不明白下一部分,解决方案说: 递归关系是

T(n) = T(n/2) + 3, T(1)=1

1)为什么常数第3部分?

if (n % 2 == 1){
        int y = P(x, (n - 1) / 2);
        return x * y * y;
    }

2)我实际上并不确切地知道为什么T(1)= 1。 我很困惑.. 在计算时间复杂度时我们应该考虑哪些操作?

例如,T(1)= 1部分必须与

相关
if (n == 0){
        return 1;
    }
if (n % 2 == 1){
        int y = P(x, (n - 1) / 2);
        return x * y * y;
    }

这一部分和我想问一下T(1)= 1是否来自if语句/ assign语句/ return语句..

之后我理解,解决了上面的递归关系,但我坚持使用递归关系本身。

请帮助我算法大师 s ..

1 个答案:

答案 0 :(得分:1)

  

在计算时间复杂度时我们应该考虑哪些操作?

答案会让你失望:你算什么操作并不重要。这就是我们在分析算法和表达时间/内存要求时使用big-Oh的原因。它是一种渐近符号,描述了对于大的n值,算法会发生什么。通过Big-Oh的定义,我们可以说1 / 2n ^ 2和10n ^ 2 + 6n + 100都是O(n ^ 2),即使它们不是相同的函数。计算所有操作,只会增加一些不变因素,这就是为什么你认为哪些操作并不重要。

通过上述,常数只是O(1)。这忽略了细节,例如10和10000都是O(1)。

有人可能会争辩说,指定表达式T(n) = T(n/2) + 3中的确切操作数不是很正确,因为没有操作定义的定义,而且相同的操作可能需要不同的时间。不同的计算机,所以准确地计算操作的数量在最好的情况下有点无意义,在最坏的情况下完全错误。更好的说法是T(n) = T(n/2) + O(1)

T(1)=1表示基本情况,它以恒定时间求解(读取:每次运算的常数)。同样,更好(更正式)的说法是T(1)=O(1)