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

Every day a Leetcode

题目来源:3266. K 次乘运算后的最终数组 II

解法1:3266. K 次乘运算后的最终数组 II

用最小堆手动模拟操作,直到原数组的最大值 mx 成为这 n 个数的最小值。

设此时还剩下 k 次操作,那么:

  • 对于前 k mod n 小的数,还可以再操作 k/n+1 次。
  • 其余元素,还可以再操作 k/n 次。

用快速幂计算操作这么多次后的结果。

代码:

/*
 * @lc app=leetcode.cn id=3266 lang=cpp
 *
 * [3266] K 次乘运算后的最终数组 II
 */

// @lc code=start
class Solution
{
private:
    const int MOD = 1e9 + 7;
    // 快速幂
    long long pow(long long x, int n)
    {
        long long res = 1;
        for (; n; n /= 2)
        {
            if (n % 2)
                res = res * x % MOD;
            x = x * x % MOD;
        }
        return res;
    }

public:
    vector<int> getFinalState(vector<int> &nums, int k, int multiplier)
    {
        // 特判
        if (multiplier == 1)
            return move(nums);

        int n = nums.size();
        int mx = *max_element(nums.begin(), nums.end());
        vector<pair<long long, int>> h(n);
        for (int i = 0; i < n; i++)
        {
            h[i] = {nums[i], i};
        }
        ranges::make_heap(h, greater<>()); // 最小堆,O(n) 堆化

        // 模拟,直到堆顶是 mx
        for (; k && h[0].first < mx; k--)
        {
            ranges::pop_heap(h, greater<>());
            h.back().first *= multiplier;
            ranges::push_heap(h, greater<>());
        }

        // 剩余的操作可以直接用公式计算
        ranges::sort(h);
        for (int i = 0; i < n; i++)
        {
            auto &[x, j] = h[i];
            nums[j] = x % MOD * pow(multiplier, k / n + (i < k % n)) % MOD;
        }
        return move(nums);
    }
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(n * logn * logmU),其中 n 是数组 nums 的长度,U=max(nums),m=multiplier。

空间复杂度:O(n),其中 n 是数组 nums 的长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值