首页 > 其他分享 >力扣刷题——3266. K 次乘运算后的最终数组 II

力扣刷题——3266. K 次乘运算后的最终数组 II

时间:2024-12-13 17:54:11浏览次数:3  
标签:力扣 nums int res multiplier long II 3266 MOD

根据题意,使用模拟解法,维护一个最小堆,始终对堆的第一个元素做乘,然后每次运算后维护堆。在实现的时候保存原有的下标,可以很方便的输出答案,有实现如下:

class Solution {
public:
    vector<int> getFinalState(vector<int>& nums, int k, int multiplier) {
        int MOD = 1e9 + 7;
        vector<int> res = nums;
        if(multiplier == 1)
            return res;
        
        vector<pair<long long, int>> h;
        for(int i = 0; i < res.size(); i++)
        {
            h.emplace_back(make_pair(nums[i], i));
        }
        make_heap(h.begin(), h.end(), greater<>());
        
        while(k)
        {
            pop_heap(h.begin(), h.end(), greater<>());
            h.back().first *= multiplier;
            push_heap(h.begin(), h.end(), greater<>());
            k--;
        }

        for(int i = 0; i < nums.size(); i++)
        {
            res[h[i].second] = h[i].first % MOD;
        }
        return res;
    }
};

但是这样实现有一个问题,有时候计算堆中的元素会超过int甚至是long long型的最大值,而直接在循环里加入取模运算的话,会导致混乱。
为了避免这个问题,采取两步计算策略。首先用模拟的方法,计算答案;之后,当堆顶元素大于等于原nums中最大值temMax时,直接用数学公式计算。
因为对第一步计算完成后的堆排序后,假如用模拟的思路去计算,只是依次计算,如对下标为0的元素做乘,之后轮到下标为1的元素,直到最后,然后不断循环。这是因为在不取mod的情况下,h[i] < h[i + 1]并且h[i] * multiplier > h[h.size()]
再使用快速幂加速,有实现:

class Solution {
public:
    long long MOD = 1e9 + 7;

    vector<int> getFinalState(vector<int>& nums, int k, int multiplier) {
        vector<int> res = nums;
        if(multiplier == 1)
            return res;
        
        vector<pair<long long, int>> h;
        for(int i = 0; i < res.size(); i++)
        {
            h.emplace_back(make_pair(nums[i], i));
        }
        make_heap(h.begin(), h.end(), greater<>());
        
        int temMax = ranges::max(nums);
        while(k && h[0].first < temMax)
        {
            pop_heap(h.begin(), h.end(), greater<>());
            h.back().first *= multiplier;
            push_heap(h.begin(), h.end(), greater<>());
            k--;
        }

        sort(h.begin(), h.end());
        int t = k / nums.size();
        for(int i = 0; i < nums.size(); i++)
        {
            
            if(k % nums.size())
            {
                k--;
                res[h[i].second] = (h[i].first % MOD) * quickPow(multiplier, t + 1) % MOD;
            }
            else
                res[h[i].second] = (h[i].first % MOD) * quickPow(multiplier, t) % MOD;
        }
        return res;
    }

    long long quickPow(long long m, long long t)
    {
        long long res = 1;
        while(t)
        {
            if(t & 1)
                res = (res * m) % MOD;
            t >>= 1;
            m = (m * m) %  MOD;
        }
        return res;
    }
};

标签:力扣,nums,int,res,multiplier,long,II,3266,MOD
From: https://www.cnblogs.com/yuhixyui/p/18605468

相关文章

  • 嵌入式必备知识-IIC协议
    此篇文章在2023年8月8日被记录1、概述IIC(Inter-IntegratedCircuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器以及其外围设备,IIC也被称为I2C,其实两者是完全相同的。它是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。两根线定义如下:数据线SDA......
  • 【力扣】数学之美:对角线与N皇后问题的完美结合
    对角线性质分析在二维数组中:主对角线(黑色)满足条件:y-x=n,其中n是一个固定值,对于同一条主对角线,n值相同,不同的主对角线n值不同。副对角线(红色)满足条件:y+x=n,其中n也是一个固定值,对于同一条副对角线,n值相同,不同的副对角线n值不同。利用这个特性,可以高效......
  • 数字组合转字母&删除二叉树节点&字符串相乘&打家劫舍ii&无序数组第k大 &无序数组前k大
    一、数字串转换为字符串1-26个数字分别代表26个字符(A-z)输入"12326〞就可以拆分为【1,2,3,2,6】、(12,3,2,6].[1,23,2,6]【1,23,26】、【12,3,26】等,将每种组合转成成对应字母输出,输出所有可能的结果返回所有可能的转换结果//将数字串转换成字母串//将数字串转换成字母......
  • 2024/12/7【哈希表】 LeetCode453 四数相加II ,知识点:defaultdict,lambda函数,dict的get
    454.四数相加II-力扣(LeetCode)代码随想录(programmercarl.com)本题解题步骤:首先定义一个unordered_map(在python中为字典),key放a和b两数之和,value放a和b两数之和出现的次数。遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。定义int变量count,用来统计a+b+......
  • IIS重写,HTTPS跳转等问题收集
     一、安装 ApplicationRequestRoutingCache二、安装URL重写 rewrite_amd64_zh-CN.msi应用程序请求路由设置1、打开IIS工具,选择上面安装的请求路由2、选择ServerProxySettings3、在中间区域,选择勾选Enableproxy,不用修改内容,当然也可以根据需求自己修改......
  • ASCII 与 Unicode 中的引号
    原文地址:https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html摘要请不要使用ASCII中的重音符号`(0x60)作为左边与ASCII中的单印号'(0x27)作为右边一起使用。就像这样(`quote')。否则,使用大多数现代字体(例如,在Windows和Mac系统上),您的文本会显得相当奇怪。只有旧......
  • ### 最大化相邻字符ASCII码之差的最小值:C语言实现与详解
    在字符串处理问题中,如何调整字符的排列以最大化相邻字符ASCII码之差的最小值是一个有趣的挑战。本文将通过一个具体的C语言实现,带你了解这一问题的解决思路和代码细节。####问题描述给定一个字符串,通过调整其字符顺序,使得字符串中任意相邻字符ASCII码之差的最小值最大。###......
  • 1321. 餐馆营业额变化增长 - 力扣(LeetCode)
    1321.餐馆营业额变化增长-力扣(LeetCode)目标输入输入:营业额customer_idnamevisited_onamount1Jhon2019/1/11002Daniel2019/1/21103Jade2019/1/31204Khaled2019/1/41305Winston2019/1/51106Elvis2019/1/61407Anna2019/1/71508Maria2019/1/8809Jaze2019/1/91101Jhon2019......
  • 1341. 电影评分 - 力扣(LeetCode)
    1341.电影评分-力扣(LeetCode)目标输入输入:评分表movie_iduser_idratingcreated_at1132020/1/121242020/2/111322020/2/121412020/1/12152020/2/172222020/2/12322020/3/13132020/2/223242020/2/25输入:用户表user_idname1Daniel2Monica3Maria4James输入:电影表movie......
  • 626. 换座位 - 力扣(LeetCode)
    626.换座位-力扣(LeetCode)目标输入输入:座位表idstudent1Abbot2Doris3Emerson4Green5Jeames输出输出:新座位表idstudent1Doris2Abbot3Green4Emerson5Jeames分析编写解决方案来交换每两个连续的学生的座位号。如果学生的数量是奇数,则最后一个学生的id不交换。按id......