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 array of positive integers nums and an integer k.
You may perform at most k operations. In each operation, you can choose one element in the array and double its value. Each element can be doubled at most once.
The score of a contiguous subarray is defined as the product of its length and the greatest common divisor (GCD) of all its elements.
Your task is to return the maximum score that can be achieved by selecting a contiguous subarray from the modified array.
Note:
Example 1:
Input: nums = [2,4], k = 1
Output: 8
Explanation:
nums[0] to 4 using one operation. The modified array becomes [4, 4].[4, 4] is 4, and the length is 2.2 × 4 = 8.Example 2:
Input: nums = [3,5,7], k = 2
Output: 14
Explanation:
nums[2] to 14 using one operation. The modified array becomes [3, 5, 14].[14] is 14, and the length is 1.1 × 14 = 14.Example 3:
Input: nums = [5,5,5], k = 1
Output: 15
Explanation:
[5, 5, 5] has a GCD of 5, and its length is 3.3 × 5 = 15.Constraints:
1 <= n == nums.length <= 15001 <= nums[i] <= 1091 <= k <= nProblem summary: You are given an array of positive integers nums and an integer k. You may perform at most k operations. In each operation, you can choose one element in the array and double its value. Each element can be doubled at most once. The score of a contiguous subarray is defined as the product of its length and the greatest common divisor (GCD) of all its elements. Your task is to return the maximum score that can be achieved by selecting a contiguous subarray from the modified array. Note: The greatest common divisor (GCD) of an array is the largest integer that evenly divides all the array elements.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Math
[2,4] 1
[3,5,7] 2
[5,5,5] 1
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3574: Maximize Subarray GCD Score
class Solution {
public long maxGCDScore(int[] nums, int k) {
int n = nums.length;
int[] cnt = new int[n];
for (int i = 0; i < n; ++i) {
for (int x = nums[i]; x % 2 == 0; x /= 2) {
++cnt[i];
}
}
long ans = 0;
for (int l = 0; l < n; ++l) {
int g = 0;
int mi = 1 << 30;
int t = 0;
for (int r = l; r < n; ++r) {
g = gcd(g, nums[r]);
if (cnt[r] < mi) {
mi = cnt[r];
t = 1;
} else if (cnt[r] == mi) {
++t;
}
ans = Math.max(ans, (r - l + 1L) * (t > k ? g : g * 2));
}
}
return ans;
}
private int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
// Accepted solution for LeetCode #3574: Maximize Subarray GCD Score
func maxGCDScore(nums []int, k int) int64 {
n := len(nums)
cnt := make([]int, n)
for i, x := range nums {
for x%2 == 0 {
cnt[i]++
x /= 2
}
}
ans := 0
for l := 0; l < n; l++ {
g := 0
mi := math.MaxInt32
t := 0
for r := l; r < n; r++ {
g = gcd(g, nums[r])
if cnt[r] < mi {
mi = cnt[r]
t = 1
} else if cnt[r] == mi {
t++
}
length := r - l + 1
score := g * length
if t <= k {
score *= 2
}
ans = max(ans, score)
}
}
return int64(ans)
}
func gcd(a, b int) int {
for b != 0 {
a, b = b, a%b
}
return a
}
# Accepted solution for LeetCode #3574: Maximize Subarray GCD Score
class Solution:
def maxGCDScore(self, nums: List[int], k: int) -> int:
n = len(nums)
cnt = [0] * n
for i, x in enumerate(nums):
while x % 2 == 0:
cnt[i] += 1
x //= 2
ans = 0
for l in range(n):
g = 0
mi = inf
t = 0
for r in range(l, n):
g = gcd(g, nums[r])
if cnt[r] < mi:
mi = cnt[r]
t = 1
elif cnt[r] == mi:
t += 1
ans = max(ans, (g if t > k else g * 2) * (r - l + 1))
return ans
// Accepted solution for LeetCode #3574: Maximize Subarray GCD Score
impl Solution {
pub fn max_gcd_score(nums: Vec<i32>, k: i32) -> i64 {
let n = nums.len();
let mut cnt = vec![0i32; n];
for i in 0..n {
let mut x = nums[i];
while x % 2 == 0 {
cnt[i] += 1;
x /= 2;
}
}
let mut ans: i64 = 0;
for l in 0..n {
let mut g: i32 = 0;
let mut mi: i32 = 1 << 30;
let mut t: i32 = 0;
for r in l..n {
g = Self::gcd(g, nums[r]);
if cnt[r] < mi {
mi = cnt[r];
t = 1;
} else if cnt[r] == mi {
t += 1;
}
let val = if t > k { g as i64 } else { (g * 2) as i64 };
ans = ans.max((r as i64 - l as i64 + 1) * val);
}
}
ans
}
fn gcd(a: i32, b: i32) -> i32 {
if b == 0 { a } else { Self::gcd(b, a % b) }
}
}
// Accepted solution for LeetCode #3574: Maximize Subarray GCD Score
function maxGCDScore(nums: number[], k: number): number {
const n = nums.length;
const cnt: number[] = Array(n).fill(0);
for (let i = 0; i < n; ++i) {
let x = nums[i];
while (x % 2 === 0) {
cnt[i]++;
x /= 2;
}
}
let ans = 0;
for (let l = 0; l < n; ++l) {
let g = 0;
let mi = Number.MAX_SAFE_INTEGER;
let t = 0;
for (let r = l; r < n; ++r) {
g = gcd(g, nums[r]);
if (cnt[r] < mi) {
mi = cnt[r];
t = 1;
} else if (cnt[r] === mi) {
t++;
}
const len = r - l + 1;
const score = (t > k ? g : g * 2) * len;
ans = Math.max(ans, score);
}
}
return ans;
}
function gcd(a: number, b: number): number {
while (b !== 0) {
const temp = b;
b = a % b;
a = temp;
}
return a;
}
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.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.