当前位置: 首页 > article >正文

Leetcode3266:K 次乘运算后的最终数组 II

题目描述:

给你一个整数数组 nums ,一个整数 k  和一个整数 multiplier 。

你需要对 nums 执行 k 次操作,每次操作中:

  • 找到 nums 中的 最小 值 x ,如果存在多个最小值,选择最 前面 的一个。
  • 将 x 替换为 x * multiplier 。

k 次操作以后,你需要将 nums 中每一个数值对 10^9 + 7 取余。

请你返回执行完 k 次乘运算以及取余运算之后,最终的 nums 数组。

代码思路:

解决方案思路

  1. 特殊情况处理:如果 multiplier 为 1,则所有元素乘以 1 不变,直接返回原数组。

  2. 初始化

    • n:数组 nums 的长度。
    • p:一个数组,用于记录每个位置的操作次数。
    • q:一个最大堆(优先队列),用于按值的大小存储元素及其索引,以便快速找到当前最大值。
    • mx:当前数列中的最大值。
  3. 前 k 次操作

    • 使用最大堆 q 初始化并找到初始最大值 mx
    • 执行 k 次操作,每次取出堆顶元素(当前最大值),将其乘以 multiplier 并重新放入堆中,同时更新该位置的操作次数 p[i]
    • 如果当前取出的最大值等于 mx,则停止循环(因为后续操作不会影响最大值的选择)。
  4. 处理剩余操作

    • 计算剩余操作次数 k 可以均匀分配给每个元素的次数 pa(整除 n)和剩余无法均匀分配的次数 k(取模 n)。
    • 遍历堆中剩余的元素,对每个元素的位置增加 1 次操作(k 次),直到 k 为 0。
  5. 计算最终状态

    • 遍历数组 nums,对于每个元素,根据其位置 i 的操作次数 p[i] 和均匀分配的操作次数 pa,计算其最终值(乘以 multiplier 的相应次幂,并取模 MOD)。
    • 使用自定义的 pow 函数计算幂次,以避免使用标准库中的 pow 函数可能带来的浮点数精度问题。
  6. 返回结果:返回经过所有操作后的最终数列。

自定义 pow 函数

  • 实现快速幂算法,用于高效计算 x 的 y 次幂并对 MOD 取模。
  • 通过不断将指数 y 减半并平方基数 x,同时根据 y 的奇偶性决定是否将当前基数 x 乘入结果 ans 中,实现高效的幂次计算。

总结

该代码通过优先队列(最大堆)高效地选择当前最大值,并通过记录每个位置的操作次数和计算幂次,最终得到经过 k 次操作后的数列状态。通过自定义的 pow 函数确保计算过程中不会超出整数范围,并避免使用浮点数运算带来的精度问题。

代码实现:

const int MOD = 1000000007; // 定义一个常量 MOD,用于取模运算,防止整数溢出

class Solution {
public:
    vector<int> getFinalState(vector<int>& nums, int k, int multiplier) {
        if (multiplier == 1) return nums; // 如果 multiplier 为 1,则任何数乘以 1 都不变,直接返回原数组

        int n = nums.size(); // 获取数组 nums 的长度
        vector<int> p(n); // 初始化一个长度为 n 的数组 p,用于记录每个位置的操作次数
        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> q; // 定义一个最大堆 q,用于存储元素值及其索引,元素值大的优先级高
        int mx = 0; // 初始化最大值 mx 为 0

        // 初始化最大堆 q 和找到初始最大值 mx
        for (int i = 0; i < n; i++) {
            q.push({nums[i], i}); // 将 nums[i] 和其索引 i 作为一对放入最大堆 q
            if (nums[i] >= mx) { // 更新最大值 mx
                mx = nums[i];
            }
        }

        // 执行 k 次操作
        while (k > 0) {
            auto [num, i] = q.top(); // 从最大堆 q 中取出当前最大值 num 及其索引 i
            q.pop(); // 弹出最大堆 q 的堆顶元素
            q.push({num * multiplier, i}); // 将 num 乘以 multiplier 后的结果和索引 i 重新放入最大堆 q
            p[i]++; // 增加索引 i 位置的操作次数
            k--; // 减少剩余操作次数

            // 如果当前取出的最大值等于 mx,则后续操作不会改变最大值的选择,可以提前退出循环
            if (num == mx)
                break;
        }

        // 计算剩余操作次数可以均匀分配给每个元素的次数 pa 和剩余次数 k'
        int pa = k / n; // 计算每个元素可以均匀分配到的操作次数
        k %= n; // 计算剩余无法均匀分配的操作次数

        // 处理剩余操作次数 k'
        while (k > 0) {
            int i = q.top().second; // 从最大堆 q 中取出当前堆顶元素的索引 i(不考虑值,因为此时值可能已变)
            q.pop(); // 弹出最大堆 q 的堆顶元素
            p[i]++; // 增加索引 i 位置的操作次数
            k--; // 减少剩余操作次数
        }

        // 计算最终状态
        for (int i = 0; i < n; i++) {
            // nums[i] 乘以 multiplier 的 (p[i] + pa) 次幂,并对 MOD 取模
            nums[i] = (nums[i] * pow(multiplier, p[i] + pa)) % MOD;
        }

        return nums; // 返回经过所有操作后的最终数列
    }

    // 自定义的 pow 函数,用于计算 x 的 y 次幂并对 MOD 取模
    long long pow(long long x, int y) {
        long long ans = 1; // 初始化结果为 1
        while (y > 0) { // 当 y 大于 0 时循环
            if ((y & 1)) { // 如果 y 是奇数
                ans = (ans * x) % MOD; // 将 ans 乘以 x 并对 MOD 取模
            }
            x = (x * x) % MOD; // 将 x 平方并对 MOD 取模
            y >>= 1; // y 右移一位,相当于 y 除以 2
        }
        return ans; // 返回最终结果
    }
};

 


http://www.kler.cn/a/443791.html

相关文章:

  • JVM性能优化一:初识内存泄露-内存溢出-垃圾回收
  • 【C#】try-catch-finally语句的执行顺序,以及在发生异常时的执行顺序
  • 【进程篇】操作系统
  • Linux线程同步
  • 如何通过HTTP API新建Collection
  • selenium工作原理
  • TanStack——为现代前端开发提供高性能和灵活的工具
  • 应用程序设置开机自启动
  • MyBatis-Plus(一)
  • 论文笔记:是什么让多模态学习变得困难?
  • Vmware 安装Ubuntu系统 服务器版本
  • 盈养科技二面
  • 3D可视化引擎HOOPS Visualize与HOOPS Luminate Bridge的功能与应用
  • 低比特语言模型 是一种利用较少比特数进行语言建模的技术
  • Nginx(Linux之Ubuntu)
  • 力扣hot100——矩阵
  • 领域驱动设计的学习分享
  • xmlrpc.php有什么用以及为何建议禁用
  • 【数据集】生菜病害检测数据集530张6类YOLO+VOC格式
  • ES6学习Symbol(五)
  • C语言与C++
  • go字符、字符串等
  • 3D 高斯溅射 (Gaussian Splatting)技术,一种实现超写实、高效渲染的突破性技术
  • 关于Unity VFX 在Spawn状态的一些笔记
  • 深入理解Kafka:核心设计与实践原理读书笔记
  • python练习:“互联网 +” 时代的出租车资源配置的数学建模(一)