剑指 Offer 16. 数值的整数次方 - 位运算logn

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.结果

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值