今天卷哥去一家国际厂面试,刚坐下打完招呼面试官就问了第一个问题。
卷哥心想这问的什么问题,过流程的吗?
面试官眉头紧皱:
看面试官的意思是对卷哥解法的时间复杂度
不太满意,卷哥想了15分钟没想出来;
卷哥:卒
正常循环求m
的n
次方,时间复杂度为O(n)
。
假设m为3
,n为9
,公式为:3 x 3 x 3 x 3 x 3 x 3 x 3 x 3 x 3
= 19683
提取重复内容( 3 * 3 )
以 m²
为基础值,那平方次数为n/2
需要额外判断n为奇数偶数,奇数得到结果值*m
为最终结果。
如果为奇数n
则时间复杂度为O(n/2-1)
,偶数n
就是O(n/2)
代码如下:
public int process(int m,int n){
int index = n/2,rm = m*m,result = rm;
for (int i = 0; i < index-1; i++) {
result *= rm;
}
if (n % 2 != 0){
result *= m;
}
return result;
}
那还有没有时间复杂度更低的算法?
上面我们是固定的两个值缩减
,效率固定了就是O(n/2),我们再分析一下:求平方的m
值是固定的,那我们能不能不固定两个值缩减,反正值固定,每一次平方后n/2
这样对数的算法效率就很快了。
但是这种情况下如果有奇数n/2
后则会漏掉一次平方的过程,所以如果n
为奇数
当前值就需要* m原始值
一次。
代码如下:
public int process(int m,int n){
int r=1,base=m;
while(n!=0){
if(n%2 != 0)
r*=base;
base*=base;
n/=2;
}
return r;
}
步骤图:
最后r x base = 19683
就等同我们上图余出来一个单个m值
需要与结果值进行平方
这种方式的时间复杂度为O(logn)
,相对时间复杂度更低。