Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given an integer array nums, an integer k, and an integer multiplier.
You need to perform k operations on nums. In each operation:
x in nums. If there are multiple occurrences of the minimum value, select the one that appears first.x with x * multiplier.After the k operations, apply modulo 109 + 7 to every value in nums.
Return an integer array denoting the final state of nums after performing all k operations and then applying the modulo.
Example 1:
Input: nums = [2,1,3,5,6], k = 5, multiplier = 2
Output: [8,4,6,5,6]
Explanation:
| Operation | Result |
|---|---|
| After operation 1 | [2, 2, 3, 5, 6] |
| After operation 2 | [4, 2, 3, 5, 6] |
| After operation 3 | [4, 4, 3, 5, 6] |
| After operation 4 | [4, 4, 6, 5, 6] |
| After operation 5 | [8, 4, 6, 5, 6] |
| After applying modulo | [8, 4, 6, 5, 6] |
Example 2:
Input: nums = [100000,2000], k = 2, multiplier = 1000000
Output: [999999307,999999993]
Explanation:
| Operation | Result |
|---|---|
| After operation 1 | [100000, 2000000000] |
| After operation 2 | [100000000000, 2000000000] |
| After applying modulo | [999999307, 999999993] |
Constraints:
1 <= nums.length <= 1041 <= nums[i] <= 1091 <= k <= 1091 <= multiplier <= 106Problem summary: You are given an integer array nums, an integer k, and an integer multiplier. You need to perform k operations on nums. In each operation: Find the minimum value x in nums. If there are multiple occurrences of the minimum value, select the one that appears first. Replace the selected minimum value x with x * multiplier. After the k operations, apply modulo 109 + 7 to every value in nums. Return an integer array denoting the final state of nums after performing all k operations and then applying the modulo.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
[2,1,3,5,6] 5 2
[100000,2000] 2 1000000
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3266: Final Array State After K Multiplication Operations II
class Solution {
public int[] getFinalState(int[] nums, int k, int multiplier) {
if (multiplier == 1) {
return nums;
}
PriorityQueue<long[]> pq = new PriorityQueue<>(
(a, b) -> a[0] == b[0] ? Long.compare(a[1], b[1]) : Long.compare(a[0], b[0]));
int n = nums.length;
int m = Arrays.stream(nums).max().getAsInt();
for (int i = 0; i < n; ++i) {
pq.offer(new long[] {nums[i], i});
}
for (; k > 0 && pq.peek()[0] < m; --k) {
long[] p = pq.poll();
p[0] *= multiplier;
pq.offer(p);
}
final int mod = (int) 1e9 + 7;
for (int i = 0; i < n; ++i) {
long[] p = pq.poll();
long x = p[0];
int j = (int) p[1];
nums[j] = (int) ((x % mod) * qpow(multiplier, k / n + (i < k % n ? 1 : 0), mod) % mod);
}
return nums;
}
private int qpow(long a, long n, long mod) {
long ans = 1 % mod;
for (; n > 0; n >>= 1) {
if ((n & 1) == 1) {
ans = ans * a % mod;
}
a = a * a % mod;
}
return (int) ans;
}
}
// Accepted solution for LeetCode #3266: Final Array State After K Multiplication Operations II
func getFinalState(nums []int, k int, multiplier int) []int {
if multiplier == 1 {
return nums
}
n := len(nums)
pq := make(hp, n)
for i, x := range nums {
pq[i] = pair{x, i}
}
heap.Init(&pq)
m := slices.Max(nums)
for ; k > 0 && pq[0].x < m; k-- {
x := pq[0]
heap.Pop(&pq)
x.x *= multiplier
heap.Push(&pq, x)
}
const mod int = 1e9 + 7
for i := range nums {
p := heap.Pop(&pq).(pair)
x, j := p.x, p.i
power := k / n
if i < k%n {
power++
}
nums[j] = (x % mod) * qpow(multiplier, power, mod) % mod
}
return nums
}
func qpow(a, n, mod int) int {
ans := 1 % mod
a = a % mod
for n > 0 {
if n&1 == 1 {
ans = (ans * a) % mod
}
a = (a * a) % mod
n >>= 1
}
return int(ans)
}
type pair struct{ x, i int }
type hp []pair
func (h hp) Len() int { return len(h) }
func (h hp) Less(i, j int) bool { return h[i].x < h[j].x || h[i].x == h[j].x && h[i].i < h[j].i }
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(x any) { *h = append(*h, x.(pair)) }
func (h *hp) Pop() (x any) { a := *h; x = a[len(a)-1]; *h = a[:len(a)-1]; return x }
# Accepted solution for LeetCode #3266: Final Array State After K Multiplication Operations II
class Solution:
def getFinalState(self, nums: List[int], k: int, multiplier: int) -> List[int]:
if multiplier == 1:
return nums
pq = [(x, i) for i, x in enumerate(nums)]
heapify(pq)
m = max(nums)
while k and pq[0][0] < m:
x, i = heappop(pq)
heappush(pq, (x * multiplier, i))
k -= 1
n = len(nums)
mod = 10**9 + 7
pq.sort()
for i, (x, j) in enumerate(pq):
nums[j] = x * pow(multiplier, k // n + int(i < k % n), mod) % mod
return nums
// Accepted solution for LeetCode #3266: Final Array State After K Multiplication Operations II
/**
* [3266] Final Array State After K Multiplication Operations II
*/
pub struct Solution {}
// submission codes start here
use std::cmp::Ordering;
use std::collections::BinaryHeap;
#[derive(Debug, Eq, PartialEq)]
struct Number {
value: i64,
pos: usize,
}
impl Ord for Number {
fn cmp(&self, other: &Self) -> Ordering {
match other.value.cmp(&self.value) {
Ordering::Equal => other.pos.cmp(&self.pos),
r => r,
}
}
}
impl PartialOrd for Number {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
const MOD: i64 = 1_000_000_007;
impl Solution {
pub fn get_final_state(nums: Vec<i32>, k: i32, multiplier: i32) -> Vec<i32> {
let multiplier = multiplier as i64;
if multiplier == 1 {
return nums;
}
let n = nums.len();
let max_number = *nums.iter().max().unwrap() as i64;
let mut heap = BinaryHeap::new();
for (i, v) in nums.into_iter().enumerate() {
heap.push(Number {
value: v as i64,
pos: i,
});
}
let mut actual_k = k;
for _ in 0..k {
if let Some(head) = heap.peek() {
if head.value >= max_number {
break;
}
}
let head = heap.pop().unwrap();
heap.push(Number {
value: head.value * multiplier,
pos: head.pos,
});
actual_k -= 1;
}
let mut result = vec![0; n];
let k = actual_k as usize;
// 牙医 shake it!
// 为什么heap.iter()会是以随机的顺序返回!
for (i, number) in std::iter::from_fn(move || heap.pop()).enumerate() {
let t = k / n + if i < k % n { 1 } else { 0 };
result[number.pos] =
(number.value % MOD * Self::quick_mulitplx(multiplier, t as i64) % MOD) as i32;
}
result
}
fn quick_mulitplx(mut x: i64, mut y: i64) -> i64 {
let mut result = 1;
while y > 0 {
if y & 1 == 1 {
result = (result * x) % MOD;
}
y = y >> 1;
x = (x * x) % MOD;
}
result
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_3266() {
assert_eq!(
vec![664480092, 763599523, 886046925, 47878852],
Solution::get_final_state(
vec![66307295, 441787703, 589039035, 322281864],
900_900_704,
641725
)
);
assert_eq!(
vec![8, 8, 4],
Solution::get_final_state(vec![4, 2, 4], 3, 2)
);
assert_eq!(
vec![8, 4, 6, 5, 6],
Solution::get_final_state(vec![2, 1, 3, 5, 6], 5, 2)
);
assert_eq!(
vec![999_999_307, 999_999_993],
Solution::get_final_state(vec![100_000, 2_000], 2, 1_000_000)
);
}
}
// Accepted solution for LeetCode #3266: Final Array State After K Multiplication Operations II
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #3266: Final Array State After K Multiplication Operations II
// class Solution {
// public int[] getFinalState(int[] nums, int k, int multiplier) {
// if (multiplier == 1) {
// return nums;
// }
// PriorityQueue<long[]> pq = new PriorityQueue<>(
// (a, b) -> a[0] == b[0] ? Long.compare(a[1], b[1]) : Long.compare(a[0], b[0]));
// int n = nums.length;
// int m = Arrays.stream(nums).max().getAsInt();
// for (int i = 0; i < n; ++i) {
// pq.offer(new long[] {nums[i], i});
// }
// for (; k > 0 && pq.peek()[0] < m; --k) {
// long[] p = pq.poll();
// p[0] *= multiplier;
// pq.offer(p);
// }
// final int mod = (int) 1e9 + 7;
// for (int i = 0; i < n; ++i) {
// long[] p = pq.poll();
// long x = p[0];
// int j = (int) p[1];
// nums[j] = (int) ((x % mod) * qpow(multiplier, k / n + (i < k % n ? 1 : 0), mod) % mod);
// }
// return nums;
// }
//
// private int qpow(long a, long n, long mod) {
// long ans = 1 % mod;
// for (; n > 0; n >>= 1) {
// if ((n & 1) == 1) {
// ans = ans * a % mod;
// }
// a = a * a % mod;
// }
// return (int) ans;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.