題目:給定一個double類型的浮點數base和int類型的整數exponent。求base的exponent次方。
方法一:
public class Solution {
public double Power(double base, int exponent) {
double result = 1;
int n = exponent;
if(exponent == 0){
return 1;
}else if(exponent < 0){
if(base == 0){
throw new RuntimeException();
}
exponent = -exponent;
}
while(exponent != 0){
if((exponent & 1) == 1){
result *= base;
}
base *= base;
exponent >>= 1;
}
return n >= 0 ? result : (1 / result);
}
}
方法二:
public class Solution {
public double Power(double base, int exponent) {
if(exponent == 0){
return 1;
}
double result = 1;
int keng = exponent;
if(exponent < 0){
if(base == 0){
throw new RuntimeException("分母不能為0");
}
exponent = -exponent;
}
while(exponent != 0){
if((exponent & 1) == 1){
result *= base;
exponent--;
}
if(exponent != 0){
result *= result;
}
exponent = exponent >> 1;
}
return keng >= 0 ? result : (1 / result);
}
}
這個題目主要考察了,數學中的一些坑,比如一個數的負數次方是正數次方的倒數,如果一個數在分母處,他不能為0;
之后就是一些優化了,千萬不要直接從頭乘到尾,他的時間復雜度是O(n)。既然是算法,利用計算機求解,應該合理的運用計算機的一些特性,比如說二進制。一般情況下使用二進制的特性都可以將一些運算的問題時間復雜度降為O(logn)
以上兩種方法都是利用二進制分解exponent的值。
方法二是我一開始想到的,用了幾個例子找規律找出來的。
比如說exponent = 101 也就5
- 當最低位為1的時候先將上一步運算(最開始為1)的結果乘base 然后將最低位的1變成0,既100。 也就是x^5 變為 x^4 相當于累成x
- 之后就是移位,將100向右移動一位,這會導致4變成2,所以在這之前要將上一部的結果平方。也就和對等了
- 最后的時候,這個exponent一定會變為1,由于exponent-1之后變成了0,這個時候只需要再乘一個base就行了,就不需要后面的平方了。
方法一:
上面的方法二的思路是我自己想的,所以這個算法步驟有些凌亂。
方法一是牛客里的一個推薦答案。
首先看這樣的一個例子
如果exponent = 100101
設底數為x
那么結果可以拆分為 x^ (2^5) * x^(2 ^ 2) * x^ (2^0)
x的(2的5次冪)乘 x的(2的2次冪)乘 x的(2的0次冪)
所以我們可以通過移位來獲得
x^100000
x^100
x^1
然后乘在一起就可以了;
每次將exponent 向右移位就將base平方
然后遇到最低位為1的時候就將base乘到結果上。
設base = 3;
exponent = 100101
初始化result = 1;
100101
最低位為1
result = result * base = 3;
base = base * base = 9移位然后平方
10010
最低位為0
base = base * base = 81移位然后平方
1001
最低位為1
result = result * base = 243;
base = base * base = 6561 移位然后平方
100
最低位為0
base = base * base = 。。。移位然后平方
10
最低位為0
base = base * base = 。。。移位然后平方
1
最低位為1
result = result * base = 結果;