时间复杂度解题思路
如何计算时间复杂度
- 找出问题规模n
- 找出基本语句
- 列出基本语句执行次数t与问题规模n的方程
- 解出t=f(n),则f(n)即为时间复杂度
例子
1、2011年计算机联考真题
x=2;
while(x<n/2){
x=2*x;
}
解题步骤:
- 问题规模n就是while(x<n/2)中的n
- 基本语句是x=2*x;
- 执行多少次x=2*x,使得x=n/2,即x=n。假设执行t次,即x乘了t个2后等于n,所以2^t=n。
- 解得t=log2n,时间复杂度为O(log2n)
2、2012年计算机联考真题
int func(int n){
if(n<=1) return 1;
return n*fact(n-1);
}
解题步骤:
- 这是一个递归,问题规模是入参n
- 基本语句是return n*fact(n-1)。换一个思路,n-1执行的次数与递归执行的次数一样,因此将n-1看做基本语句
- 递归的结束是n<=1,因此执行多少次n-1后n<=1,显而易见,n减n次1后满足n<=1的条件
- O(n)即为时间复杂度
3、2014年计算机联考真题
count=0;
for(k=1;k<=n;k*=2){
for(j=1;j<=n;j++){
count++;
}
}
解题步骤:
问题规模有两个,先看内层:
- 问题规模n就是j<=n中的n
- 基本语句看似是count++,实则应该是j++,这样方便找对应的方程
- j初始是1,执行多少次j++后j<=n?显然执行n-1次后满足条件,即t=n-1
- 因此时间复杂度为O(n)
再看外层:
- 问题规模n就是k<=n中的n
- 同内层的j++,这里将k*=2看做基本语句
- 假设k乘t次2,可以使k<=n。即2^t=n
- 解3中的方程,可得时间复杂度是O(log2n)。
结合内外层:
因为是嵌套for循环,是一个排列组合问题,应该将内外层时间复杂度相乘。故时间复杂度为O(nlog2n)
4、2017年计算机联考真题
int func(int n) {
int i=0, sum=0;
while(sum < n)
sum += ++i;
return i;
}
解题步骤:
- 问题规模n就是while(sum < n)中的n
- sum += ++i 可以分解为 i+1; sum = sum + i; 基本语句为sum = sum + i;
- 问:执行多少次 sum = sum + i,可以使 sum = n ?
执行次数t | sum |
---|---|
1 | sum = 0 + 1 = 1 |
2 | sum = 0 + 1 + 2 = 3 |
3 | sum = 0 + 1 + 2 + 3 = 6 |
4 | sum = 0 + 1 + 2 + 3 + 4 = 10 |
可见,执行次数t与sum可构成一个代数式, 10 = (1 + 4) * 4 / 2 即:sum = (1 + t) * t / 2
- 根据步骤3可得出方程t2 = sum = n,解得 t = n1/2,则该函数的时间复杂度为O(n1/2)
难点
难点在于找出第三步的方程式
注:一个问题要搞清楚出现的所有概念以及概念之间的关系,这样这个问题按照逻辑就很容易解答。