力扣超级次方问题labuladong

372. 超级次方

1、处理b,b是个数组,无法组成一个整型,因此a的b次方需要特别处理。处理方法是采取递归的方法,
例如b = 1,5,6,4,因此a的b次方 = a^4 * (a的1,5,6次方)的10次方,因此就可以看到把原来的a的1564次方转化为子问题a的156次方,即superpow

2、常数次方的处理,由于这里的常数是1到9,a的数值有可能会很大导致a的常数次方超出整型,因此题目要求(a * b) % base,a * b可能会溢出。
证明可得(a * b) % base = (a % base)(b % base) % base,即等价于每个因子求模后再对乘积求模
即mypow

实现部分

1、注释的部分采用的是for循环求常数幂,这里先对a求模,对应的是乘数因子求模,res求模的意义是每次乘积都需要求模
时间复杂度是O(b.size())

2、未注释部分采用的是快速幂,时间复杂度为O(log(b.size()))。这里可能会有个疑惑就是为什么每次递归后、乘积后都需要取模?虽然是符合了上面的规律但这样做好像算式中取模次数好像非常多?个人理解是只要符合因子取模、乘积取模即可,不管取模多少次,结果都不会变,即9模2不管模多少次都是1,所以多次取模不影响结果,而且还可以防止溢出问题

class Solution {
public:
    int base = 1337;
    int mypow(int a,int k){
        if(k == 0)return 1;
        a %= base;
        if(k % 2 == 1){
            return (a * mypow(a,k - 1)) % base;
        }
        else{
            int sub = mypow(a,k / 2);
            return (sub * sub) % base;
        }
    }
    /*
    int mypow(int a,int k){
        a %= base;
        int res = 1;
        for(int _ = 0;_ < k;++_){
            res *= a;
            res %= base;
        }
        return res;
    }
    */
    int superPow(int a, vector<int>& b) {
        if(b.empty())return 1;
        int last = b.back();
        b.pop_back();
        int part1 = mypow(a,last);
        int part2 = mypow(superPow(a,b),10);

        return (part1 * part2) % base;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值