1.题目
2.思路
2.1特殊的例子有哪些?
n == 0, return 1; // 0 ^ 0 =1
x == 0, return 0;
n = −2147483648时候,比较特殊,一定要测试。
n < 0时候,需要取反操作。(x = 1 / x; n 也要取反,但是不能直接写成 n = -n,数据溢出)
2.2思路
如果直接暴力,挨个相乘,明显会超时。O(2^31) > 10 ^8
所以想到了位运算,每次用与操作n & 1,判断最后一位是否为1, 是1的话直接乘x。
更新x *= x;
更新b = n >> 1;
循坏条件:while(n != 0)
2.3易错点
n == −2147483648时候, 需要long b = n; b = -b. 因为int 类型的n 数据范围[−2147483648,2147483647]
错误示例1: n = -n.
错误示例2:long b = n; b = -n
class Solution {
public double myPow(double x, int n) {
// if(n == 0) return 1.0;
// if(x == 1) return 1.0;
// int flag = 1;
// // 负数
// if(n < 0)flag = -1;
// n = n * flag; // 这里如果n = -2147483648 , 转化为正数,会越界。可以用long 存储。
// System.out.println(n +">>");
// double[]arr = new double[32];
// Arrays.fill(arr, 1);
// arr[1] = x;
// for(int i = 2 ; i < 32; i++){
// arr[i] = arr[i - 1] * arr[i - 1] ;
// }
// int[]bits = new int[32];
// int cnt = 0;
// for(int i = 1 ; i < 32; i++){
// int t = n & 1;
// bits[i] = t;
// n = n >> 1;
// cnt = i;
// // System.out.println(bits[i] + ".." + cnt);
// if(n == 0){
// break;
// }
// }
// // 计算结果
// double ans = 1;
// for(int i = 1 ; i <= cnt; i++){
// // System.out.println(bits[i] + ".." + arr[i] + ">>" + flag);
// if(arr[i] > 100000000 && flag == -1){
// return 0;
// }
// if(bits[i] != 0)
// ans *= arr[i] * bits[i];
// }
// if(flag == -1)
// ans = 1.0 / ans;
// return ans;
long b = n;
double ans = 1.0;
// 0 ^ 0 = 1
if(n == 0) return 1;
if(x == 0) return 0;
// 负数的判断
if(n < 0){
b = -b; //注意这里不能写成-n , 因为n 是int, -n 还是整数
x = 1.0 / x;
}
// System.out.println(Math.pow(2, 31));
while(b != 0){
// System.out.println(ans +".." + x +">>" + b);
if((b & 1) == 1)ans *= x;
x *= x;
b = b >> 1;
}
return ans;
}
}
3.结果