(快速幂 + 模拟) LeetCode 2961. 双模幂运算

原题链接

一. 题目描述

给你一个下标从 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 。
因此,返回 [] 作为答案。
 

提示:

1 <= variables.length <= 100
variables[i] == [ai, bi, ci, mi]
1 <= ai, bi, ci, mi <= 103
0 <= target <= 103

二. 解题思路

本题意思非常简单,就是通过幂运算和取模来计算结果和给定的 target 的值是否相同,这里我们运用到一个比较实用和高效的方法求解幂运算—快速幂

快速幂就是通过将指数进行二进制分解,利用指数的二进制表示来逐步计算幂的结果。具体来说,快速幂算法的时间复杂度为O(log n),与传统的幂运算算法相比,其效率有了极大的提高。这种算法通过将指数b表示为二进制形式,并利用幂的运算法则(a^(m+n) = a^m * a^n)将a^b拆分成更小的幂的乘积。通过逐步计算这些小幂的值,最后将它们相乘,即可得到a^b的结果。快速幂算法不仅适用于普通的幂运算,还广泛应用于大数运算、模幂运算和优化算法等方面,特别是在处理大数和需要高效计算的情况下显得尤为重要。‌

 这里我们举个例子(3^5 % 5 = 3):

图画的有点丑,不要在意哈哈哈,言归正传,我们将3 的5 次方通过二进制拆分之后可以看出,如果二进制中某一位为1,则代表该位可以进行乘法,那我们只需要对幂运算拆分成很多个小的幂运算计算即可,(b & 1) 意思就是判断指数的二进制下一位是不是1,如果是,则进行乘法运算并对mod取模,如果不是则继续对底数进行平方,然后让指数向右移动一位,即(b = b >> 1)。

这样计算可以大大的优化时间复杂度,对一些大数的计算有很大的优化。

话不多说!!上代码!!

三. 代码

class Solution {
public:
    int qmi(int a, int b, int mod){
        int res = 1;
        while(b){
            if(b & 1) res = res * a % mod;
            a = a *a % mod;
            b >>= 1;
        }
        return res;
    }
    vector<int> getGoodIndices(vector<vector<int>>& variables, int target) {
        vector<int> res;
        for(int i = 0; i < variables.size(); i++){
            int temp = qmi(variables[i][0], variables[i][1], 10);
            int temp2 = qmi(temp, variables[i][2], variables[i][3]);
            if(temp2 == target){
                res.push_back(i);
            }
        }
        return res;
    }
};

四. 总结

时间复杂度:O(N∗Log(M));

空间复杂度:O(1)。

喜欢的话给个关注吧!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值