leetcode 3266. K 次乘运算后的最终数组 II
给你一个整数数组 nums
,一个整数 k
和一个整数 multiplier
。
你需要对 nums
执行 k
次操作,每次操作中:
- 找到
nums
中的 最小 值x
,如果存在多个最小值,选择最 前面 的一个。 - 将
x
替换为x * multiplier
。
k
次操作以后,你需要将 nums
中每一个数值对 109 + 7
取余。
请你返回执行完 k
次乘运算以及取余运算之后,最终的 nums
数组。
示例 1:
输入:nums = [2,1,3,5,6], k = 5, multiplier = 2
输出:[8,4,6,5,6]
解释:
操作 | 结果 |
---|---|
1 次操作后 | [2, 2, 3, 5, 6] |
2 次操作后 | [4, 2, 3, 5, 6] |
3 次操作后 | [4, 4, 3, 5, 6] |
4 次操作后 | [4, 4, 6, 5, 6] |
5 次操作后 | [8, 4, 6, 5, 6] |
取余操作后 | [8, 4, 6, 5, 6] |
示例 2:
输入:nums = [100000,2000], k = 2, multiplier = 1000000
输出:[999999307,999999993]
解释:
操作 | 结果 |
---|---|
1 次操作后 | [100000, 2000000000] |
2 次操作后 | [100000000000, 2000000000] |
取余操作后 | [999999307, 999999993] |
提示:
1 <= nums.length <= 104
1 <= nums[i] <= 109
1 <= k <= 109
1 <= multiplier <= 106
解题思路
快速幂
因为和坐标有关系,先定义以下变量
设置了一个node节点来存储元素的值value和对应的坐标index
获取最大值max
数组的长度length
这道题可以分以下思路
1.先把节点排序,在不超过最大值的情况下,和操作次数不超过k的情况下,用优先队列直接操作。复杂度不会超过32 * length。
2.当前的数组中,因为每一个元素 value * m >= max, 所以可以这么说,当操作 length 次的时候,就会是每个数字都会被操作一次.
可以用反证法来证明,若是不是每个数字都会被操作一次,那肯定是最大值没有操作, 但是每个值 value * m >= max 所以,操作 length - 1次的时候,所有的值,都比max大了,那么,max一定能被操作。
3.剩下的次数k中, 就会分为两部分,分别对length取商得到t1,对length取模得到t2
4.对于t2的操作,因为会小于length, 所以可以和步骤一 一样操作。
5.对于t1的操作,根据步骤二的理论,就相当于每个元素都会 * t1, 所以可以用快速幂来解答。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | public int [] getFinalState( int [] nums, int k, int m) { if (m == 1 ) { return nums; } int length = nums.length; Node[] nodes = new Node[length]; int max = 0 ; for ( int i = 0 ; i < length; i++) { nodes[i] = new Node(nums[i], i); max = Math.max(max, nums[i]); } int v = getList(nodes, k, m, max); if (v == k) { for (Node node : nodes) { nums[node.index] = ( int ) (node.value % 1000000007 ); } return nums; } k -= v; int t1 = k / length; int t2 = k % length; getList(nodes, t2, m); int mm = mm(m, t1); // System.out.println(v + " " + t1 + " " + t2 + " " + mm); for (Node node : nodes) { nums[node.index] = ( int ) (node.value * mm % 1000000007 ); } return nums; } public int mm( int m, int t1) { long item = m; long sum = 1 ; while (t1 != 0 ) { if ((t1 & 1 ) == 1 ) { sum = sum * item % 1000000007 ; } item = item * item % 1000000007 ; t1 >>= 1 ; } return ( int ) sum; } private int getList(Node[] nodes, int k, int m, int max) { int count = 0 ; PriorityQueue<Node> queue = new PriorityQueue<>((a, b) -> a.value == b.value ? Integer.compare(a.index, b.index) : Long.compare(a.value, b.value)); Collections.addAll(queue, nodes); while (queue.peek().value * m <= max) { Node poll = queue.poll(); poll.value = poll.value * m ; queue.add(poll); count++; if (count == k) { break ; } } return count; } private void getList(Node[] nodes, int k, int m) { int count = 0 ; PriorityQueue<Node> queue = new PriorityQueue<>((a, b) -> a.value == b.value ? Integer.compare(a.index, b.index) : Long.compare(a.value, b.value)); Collections.addAll(queue, nodes); while (count < k) { Node poll = queue.poll(); poll.value = poll.value * m ; queue.add(poll); count++; } for (Node node : nodes) { node.value = node.value % 1000000007 ; } } private static class Node { private long value; private int index; public Node( long value, int index) { this .value = value; this .index = index; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具