力扣每日一题 双模幂运算

 中等   数学

给你一个下标从 0 开始的二维数组 variables ,其中 variables[i] = [ai, bi, ci, mi],以及一个整数 target

如果满足以下公式,则下标 i好下标

  • 0 <= i < variables.length
  • ((aibi % 10)ci) % mi == target

返回一个由 好下标 组成的数组,顺序不限

示例 1:

输入:variables = [[2,3,3,10],[3,3,3,1],[6,1,1,4]], target = 2
输出:[0,2]
解释:对于 variables 数组中的每个下标 i :
1) 对于下标 0 ,variables[0] = [2,3,3,10] ,(23 % 10)3 % 10 = 2 。
2) 对于下标 1 ,variables[1] = [3,3,3,1] ,(33 % 10)3 % 1 = 0 。
3) 对于下标 2 ,variables[2] = [6,1,1,4] ,(61 % 10)1 % 4 = 2 。
因此,返回 [0,2] 作为答案。

示例 2:

输入:variables = [[39,3,1000,1000]], target = 17
输出:[]
解释:对于 variables 数组中的每个下标 i :
1) 对于下标 0 ,variables[0] = [39,3,1000,1000] ,(393 % 10)1000 % 1000 = 1 。
因此,返回 [] 作为答案。

思路

这道题算是一道数学题,由题目中所要求,其中要计算到一个数的多少次幂对m取模,观察取值范围,指数的最大取值到了1000,所以想着先把数算出来在取模是不行的,long long也存不下,我们知道,数a的b次幂就是b个a相乘,那么对于乘数来说,我们先求出这个数在取模,和对乘数运算中每个数取模在相乘答案是一样的,所以我们边乘边取模,最后得到的数和题目所给比较一下即可。求幂运算,对于这题来说暴力相乘即可,用快速幂会更快。至于快速幂,如果有不会的小伙伴我打算后面写一个相关的文章来介绍一下。

解题过程

这题我们直接遍历数组,对于每个条目,按题目要求模拟即可,然后求幂时注意取模即可。

 这里给出暴力和快速幂两种代码

暴力

class Solution {
public:
    vector<int> getGoodIndices(vector<vector<int>>& variables, int target) {
        vector<int> ans;

        for(int i=0;i<variables.size();i++)
        {
            
            int a=variables[i][0],b=variables[i][1],c=variables[i][2],m=variables[i][3];

            int kk=comp(a,b,10);

            long long k=comp(kk,c,m);

            if(k==target)
            {
                ans.push_back(i);
            }

        }

        return ans;
    }

    long long comp(int a,int b,int c)//用来求取模后的幂
    {
        long long res=1;

        for(int i=0;i<b;i++)
        {
            res*=a%c;
            res%=c;
        }
       
        return res%c;
    }
};

快速幂

class Solution {
public:
    vector<int> getGoodIndices(vector<vector<int>>& variables, int target) {
        vector<int> ans;

        for(int i=0;i<variables.size();i++)
        {
            
            int a=variables[i][0],b=variables[i][1],c=variables[i][2],m=variables[i][3];

            int kk=comp(a,b,10);

            long long k=comp(kk,c,m);

            cout<<k<<endl;
            if(k==target)
            {
                ans.push_back(i);
            }

        }

        return ans;
    }

    long long comp(int a,int b,int c)
    {
        long long res=1,base=a;

        while(b)
        {
            if(b&1)
            {
                res*=base%c;
                
            }
            b>>=1;
            base%=c;
            base*=base%c;
        }
       
        return res%c;
    }
};

在力扣提交时可以看出明显的速度差距,快速幂在处理大规模大数时效率还是蛮高的

最上面那个是快速幂运算, 下面三个是暴力,虽然力扣有时候测评速度不准,但是这个时间上有着明显的差距,当数据量更大时速度差距会更明显,这题数据还是弱了,没有hack暴力法。这几天我会写一个快速幂的讲解,希望大家多多点赞支持!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值