zoukankan      html  css  js  c++  java
  • leetcode Super Pow

    题目描述:

       superPow(int a, int[] b),b是一个int数组,每个元素都是正的个位数,组合起来表示一个正整数,例如b=[1,2,3]表示123,求解a^b mod 1337.

    思路描述:

       本题的难点是当a和b足够大时会造成溢出,因此应考虑其他算法来实现。

       理论支持(转幂算法):

                      (a^b) mod c = ((a mod c)^b) mod c ----公式1

                      (x*y) mod c = ((x mod c) * (y mod c)) mod c  :积的取余等于取余的积的取余。 -----公式2

       基于上述的算法,有:

              首先将a对c取余,不妨设余数值为x,则:(a^b) mod c = (x^b)mod c    ---基于式1

              (x^b)mod c = (((x ^ (b/2)) mod c) * ((x ^ (b/2)) mod c) ) mod c    :b为偶数

              (x^b)mod c = (((x ^ (b/2)) mod c) * ((x ^ (b/2)) mod c) * x) mod c  :b为奇数

                                                                                                            ----基于式2

       基于上述分析,问题解决思路如下: 首先将a对1337取余;然后将数组组成的整数除2,然后带入superPow(a, b/2),递归进行一直到b为0返回。

       其中b/2实现比较绕,可以考虑我们初学除法时的步骤,实现算法与之很类似。

    leetcode上的AC代码:

        

    public class Solution {
        public int superPow(int a, int[] b) {
            /*数学公式:
                (a^b) mod c = ((a mod c)^b)
                (x*y) mod c = ((x mod c)*(y mod c)) mod c :积的取余等于取余的积的取余
                
            */
            if(b.length == 0 || isZero(b)){
                return 1;
            }
            
            a = a%1337;
            boolean flag = false;
            if(b[b.length-1]%2 == 1){
                flag = true;  //幂次是奇数
            }
            div(b,2);
            int ans = superPow(a,b);
            ans = (ans*ans)%1337;
            if(flag){
                ans = (ans*a)%1337;
            }
            
            return ans;
            
        }
        
        boolean isZero(int[] num){// 判断数组组成的整数是否为0
            for(int i=num.length-1; i>=0; i--){
                if(num[i]>0){
                    return false;
                }
            }
            
            return true;
        }
        
        void div(int[] num, int y){  //完成一次数组组成的整数的除法
            int tmp = 0;
            for(int i=0; i<num.length; i++){
                num[i] += tmp*10;
                tmp = num[i]%y;
                num[i] = num[i]/y;
            }
        }
    }
  • 相关阅读:
    Golang——内存分区理解:代码区、数据区、堆区、栈区
    Golang基础——工程管理:同一目录和不同目录的文件引用
    Golang基础——函数,作用域,匿名函数,递归
    pandas 学习
    git学习
    Golang基础——跳转语句 break,continue,goto
    Golang基础——for循环
    Golang基础——if语句,switch语句
    while你爱不爱我
    js判断年份
  • 原文地址:https://www.cnblogs.com/bywallance/p/6031506.html
Copyright © 2011-2022 走看看