2025-04-02:K 次乘运算后的最终数组Ⅱ。用go语言,给定一个整数数组 nums,以及两个整数 k 和 multiplier。你需要对 nums 数组进行 k 次操作。每次操作的流程如下:
1.找到 nums 中的最小值 x,若有多个最小值则选择最早出现的那一个。
2.用 multiplier 乘以 x,然后将其替换掉原来的 x。
完成 k 次这样的操作后,对 nums 数组中的每个元素进行模 1000000007 的运算。
最后,返回处理后的 nums 数组。
1 <= nums.length <= 10000。
1 <= nums[i] <= 1000000000。
1 <= k <= 1000000000。
1 <= multiplier <= 1000000。
输入: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] |
题目来自leetcode3266。
multiplier == 1
,那么每次操作不会改变 nums
的值,直接返回 nums
。nums
中的每个元素及其原始索引存入一个最小堆中。堆的比较规则是:首先比较值,值小的优先;如果值相同,则索引小的优先。nums
中的最大值 mx
。k
次操作:mx
且 k > 0
,就执行以下操作:x
(当前最小值)。x
的值乘以 multiplier
。x
重新放回堆中。k
减 1。mx
的值。这样可以避免在后续处理中频繁操作堆。k
次操作:k
仍然大于 0,说明所有元素都已经至少是 mx
的值。此时,剩余的 k
次操作可以均匀分配到每个元素上。k
次操作,n
个元素。t = k / n
次乘法。k % n
个元素会额外进行一次乘法。(current_value * (multiplier^t)) % 1000000007
,其中 t
是该元素的乘法次数。nums
。O(n)
(如果使用堆化操作)。k
次操作:每次堆操作是 O(log n)
,最多进行 min(k, n log (mx))
次操作(因为每次操作至少让一个元素翻倍,最多 log(mx)
次)。O(n log n)
。O(log k)
次(因为 t
可以是 k/n
)。O(n log n + min(k, n log mx) log n + n log k)
。O(n)
。O(1)
。O(n)
。nums = [2,1,3,5,6]
,k = 5
,multiplier = 2
。[ (1,1), (2,0), (3,2), (5,3), (6,4) ]
,mx = 6
。k
次操作:(1,1)
,乘以 2
得 (2,1)
,放回堆。堆:[ (2,0), (2,1), (3,2), (5,3), (6,4) ]
,k = 4
。(2,0)
,乘以 2
得 (4,0)
,放回堆。堆:[ (2,1), (3,2), (4,0), (5,3), (6,4) ]
,k = 3
。(2,1)
,乘以 2
得 (4,1)
,放回堆。堆:[ (3,2), (4,0), (4,1), (5,3), (6,4) ]
,k = 2
。(3,2)
,乘以 2
得 (6,2)
,放回堆。堆:[ (4,0), (4,1), (5,3), (6,2), (6,4) ]
,k = 1
。(4,0)
,乘以 2
得 (8,0)
,放回堆。堆:[ (4,1), (5,3), (6,2), (6,4), (8,0) ]
,k = 0
。k = 0
,无需进一步操作。[ (4,1), (5,3), (6,2), (6,4), (8,0) ]
。nums[1] = 4 % 1000000007 = 4
。nums[3] = 5 % 1000000007 = 5
。nums[2] = 6 % 1000000007 = 6
。nums[4] = 6 % 1000000007 = 6
。nums[0] = 8 % 1000000007 = 8
。nums = [8,4,6,5,6]
。package main
import (
"container/heap"
"fmt"
"sort"
)
func quickMul(x, y, m int64)int64 {
res := int64(1)
for y > 0 {
if (y & 1) == 1 {
res = (res * x) % m
}
y >>= 1
x = (x * x) % m
}
return res
}
func getFinalState(nums []int, k int, multiplier int) []int {
if multiplier == 1 {
return nums
}
n, m := len(nums), int64(1e9+7)
mx := 0
var v minHeap
for i, num := range nums {
mx = max(mx, num)
v = append(v, pair{int64(num), i})
}
heap.Init(&v)
for ; v[0].first < int64(mx) && k > 0; k-- {
x := heap.Pop(&v).(pair)
x.first *= int64(multiplier)
heap.Push(&v, x)
}
sort.Slice(v, func(i, j int)bool {
return v[i].first < v[j].first || v[i].first == v[j].first && v[i].second < v[j].second
})
for i := 0; i < n; i++ {
t := k / n
if i < k%n {
t++
}
nums[v[i].second] = int((v[i].first % m) * quickMul(int64(multiplier), int64(t), m) % m)
}
return nums
}
type pair struct {
first int64
second int
}
type minHeap []pair
func (h minHeap) Len() int {
returnlen(h)
}
func (h minHeap) Less(i, j int) bool {
return h[i].first < h[j].first || h[i].first == h[j].first && h[i].second < h[j].second
}
func (h minHeap) Swap(i, j int) {
h[i], h[j] = h[j], h[i]
}
func (h *minHeap) Push(x interface{}) {
*h = append(*h, x.(pair))
}
func (h *minHeap) Pop() interface{} {
n := len(*h)
res := (*h)[n-1]
*h = (*h)[0 : n-1]
return res
}
func main() {
nums := []int{2, 1, 3, 5, 6}
k := 5
multiplier := 2
result := getFinalState(nums, k, multiplier)
fmt.Println(result)
}
# -*-coding:utf-8-*-
import heapq
defquick_mul(x, y, m):
res = 1
while y > 0:
if y & 1: # 如果 y 的最低位为 1
res = (res * x) % m
y >>= 1# y 右移一位
x = (x * x) % m # x 自身平方并取模
return res
defget_final_state(nums, k, multiplier):
if multiplier == 1:
return nums
n = len(nums)
m = 10**9 + 7
mx = max(nums)
min_heap = []
# 使用最小堆存储元组 (num, index)
for index, num inenumerate(nums):
heapq.heappush(min_heap, (num, index))
# k 次替换操作
while min_heap[0][0] < mx and k > 0:
x = heapq.heappop(min_heap) # 取出最小值
x_value, x_index = x
x_value *= multiplier # 乘以 multiplier
heapq.heappush(min_heap, (x_value, x_index)) # 将新值重新入堆
k -= 1
# 将堆中的元素按数值和原始索引排序
sorted_heap = sorted(min_heap, key=lambda x: (x[0], x[1]))
# 更新原数组的值
for i inrange(n):
t = k // n
if i < k % n:
t += 1
nums[sorted_heap[i][1]] = (sorted_heap[i][0] % m) * quick_mul(multiplier, t, m) % m
return nums
# 示例
nums = [2, 1, 3, 5, 6]
k = 5
multiplier = 2
result = get_final_state(nums, k, multiplier)
print(result)
我们相信 Go 语言和算法为普通开发者提供了强有力的“面试利器”,并致力于分享全面的编程知识。在这里,您可以找到最新的 Go 语言教程、算法解析、提升面试竞争力的秘籍以及行业动态。