算法之数字运算

一、快速幂

(1)普通算法:求a^b%m的时间复杂度为O(b)

(2)快速幂:求a^b%m的时间复杂度为O(logb)

  比喻:我们已知 2^3  求 2^6,不就是 2^3 * 2^3嘛。快速幂就是这个原理;当遇到奇数时2 ^ 5,就是 2 * 2 ^ 4 。

  求a ^ b快速幂的基本思路:

    1)当b是奇数时,那么有 a^b = a * a^*(b-1)

    2)当b是偶数时,那么有 a^b = a^(b/2) * a^(b/2)

    如:2^10 = 2^5 * 2^5

      2^5 = 2 * 2^4

      2^4 = 2^2 * 2^2

      2^1 = 2 * 2^0

  求 a^b%m

//暗指int为长整型
public int fun(int a,int b,int m){
    int ans=1;
    while(b>0){
        //位与&运算要比%运算要快  
        if(1==(b&1)){
     //对乘法的结果求模,等价于先对每个因子都求模,然后对因子相乘的结果再求模。
            ans=ans*a%m;
        }
        a=(a%m)*(a%m)%m;
        b=b>>1;
    }
    return ans;
}

  

//2147483647
//[2,0,0]
//k=1337
//即求pow(2147483647,200)%1337
class Solution {
    public int superPow(int a, int[] b) {
        int res=1;
        for(int i=0;i<b.length;i++){
            res=func(res,10,1337)*func(a,b[i],1337)%1337;
            // qpow(res,10,1337) * qpow(a, x, 1337) % 1337;
        }
        return res;
    }
    public int func(int x,int y,int k){
        int ans=1;
        while(y>0){
            if((y&1)==1){
                ans=ans*x%k;
            }
            // x=x*x%k;
            x=(x%k)*(x%k)%k;
            y=y>>1;
        }
        return ans;
    }
}

二、java的左移与右移

  左移代表乘,左移一位代表乘2,左移两位代表乘4,依次递增           12<<1=24    12<<2=48 

  右移代表除,  右移一位代表除2,右移两位代表除4,依次递增            12>>1=6      12>>2=3

  System.out.println(12>>2)//结果为3

  System.out.println(12<<1)//结果为24

posted on 2020-03-23 20:55  hdc520  阅读(630)  评论(0编辑  收藏  举报

导航