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 <= 1041 <= nums[i] <= 1091 <= k <= 1091 <= 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, 所以可以用快速幂来解答。
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;
}
}


浙公网安备 33010602011771号