- Interview Questions
- /
- Problems
- /
- Minimum Array Sum
Minimum Array Sum
Spend a limited number of "halve" and "subtract k" operations on an array to make its sum as small as possible. A test of turning per-element choices under two budgets into a knapsack-style DP. Solve it below in Python or JavaScript, then read the walkthrough.
Problem
You're given an integer array nums and three integers k, op1, and op2. You can apply two kinds of operations:
- Halve: pick an index
iand replacenums[i]withnums[i] / 2, rounded up. You can do this at mostop1times in total, and at most once per index. - Subtract: pick an index
iwherenums[i] ≥ kand replacenums[i]withnums[i] - k. You can do this at mostop2times in total, and at most once per index.
The same index may receive both operations (each at most once), in either order. The "nums[i] ≥ k" check for Subtract uses the value at the moment you subtract, so the order can matter.
Return the smallest possible sum of nums after applying any number of operations within these limits. You don't have to use all of them.
Example 1
- Input
- nums = [11, 6, 20], k = 7, op1 = 2, op2 = 3
- Output
- 10
20 is halved to 10 and then reduced by 7 to 3. 11 has 7 subtracted to get 4. 6 is halved to 3. The sum is 3 + 4 + 3 = 10.
Example 2
- Input
- nums = [7], k = 5, op1 = 1, op2 = 1
- Output
- 1
Halving first gives 4, which is below k, so the subtraction is no longer allowed. Subtracting first gives 2, and halving that gives 1.
Example 3
- Input
- nums = [5, 5, 5], k = 10, op1 = 3, op2 = 3
- Output
- 9
No value is ever at least 10, so only halving helps: 3 + 3 + 3 = 9.
Constraints
- 1 ≤ nums.length ≤ 100
- 0 ≤ nums[i] ≤ 10⁵
- 0 ≤ k ≤ 10⁵
- 0 ≤ op1, op2 ≤ nums.length
Practice
Runs 15 tests in your browser. Python loads on the first run (about 6 MB, then cached). Press ⌘/Ctrl + Enter to run.
Get asked Minimum Array Sum in a real interview?
Interview Solver gives you a working solution live, during your actual coding interview. Invisible to screensharing.
How to solve Minimum Array Sum
Pattern: 0/1 knapsack DP with two budgets
Each element ends up in one of four states: untouched, halved, reduced by k, or both. Its final value only depends on its own state, and the only thing linking elements together is the two shared budgets. That is a knapsack: items (elements), each with a few options, each option costing some of budget 1 and some of budget 2.
So define dp[a][b] as the smallest sum of the elements processed so far using at most a halvings and b subtractions. For each new element, try all four options and take the best.
The "both" option needs one extra thought. Halving then subtracting gives ceil(x / 2) - k, which is smaller, but it is only legal if ceil(x / 2) ≥ k. Subtracting then halving gives ceil((x - k) / 2) and only needs x ≥ k. Take the best legal one.
Greedy choices (halve the largest values, subtract from the rest) are tempting, but the interaction between the two operations and the ≥ k rule makes them fail on some inputs. The DP avoids having to prove a greedy rule.
Approach 1: Try every assignment
Recursively choose one of up to four options for each element and keep the best total that stays within both budgets. Correct, but it explores up to 4ⁿ combinations.
Time O(4ⁿ) · Space O(n) recursion depth
Approach 2: Memoized recursion on (index, op1 left, op2 left)
The best result for the suffix starting at i only depends on i and the remaining budgets, so cache it. There are n · (op1 + 1) · (op2 + 1) states, each trying four options.
Time O(n · op1 · op2) · Space O(n · op1 · op2)
Approach 3: Bottom-up DP over the two budgets
- Start with
dp[a][b] = 0for all0 ≤ a ≤ op1,0 ≤ b ≤ op2. - For each
x, computehalf = ceil(x / 2),sub = x - k(ifx ≥ k), andbothas the best legal order. - Update
dp[a][b]foraandbgoing downward, so each update reads the values from before this element: the min ofdp[a][b] + x,dp[a-1][b] + half,dp[a][b-1] + sub, anddp[a-1][b-1] + both. - Return
dp[op1][op2].
Iterating the budgets downward is the usual 0/1 knapsack trick that lets one table serve as both the old and new layer.
Time O(n · op1 · op2) · Space O(op1 · op2)
| Approach | Time | Space |
|---|---|---|
| Try every assignment | O(4ⁿ) | O(n) recursion depth |
| Memoized recursion on (index, op1 left, op2 left) | O(n · op1 · op2) | O(n · op1 · op2) |
| Bottom-up DP over the two budgets | O(n · op1 · op2) | O(op1 · op2) |
Solution code
Try the practice editor first. Both solutions pass every test above.
Minimum Array Sum solution in Python
def min_array_sum(nums: list[int], k: int, op1: int, op2: int) -> int:
dp = [[0] * (op2 + 1) for _ in range(op1 + 1)]
for x in nums:
half = (x + 1) // 2
both = None
if x >= k:
both = (x - k + 1) // 2
if half >= k:
both = half - k if both is None else min(both, half - k)
for a in range(op1, -1, -1):
row, prev = dp[a], dp[a - 1] if a else None
for b in range(op2, -1, -1):
best = row[b] + x
if prev is not None:
best = min(best, prev[b] + half)
if b and x >= k:
best = min(best, row[b - 1] + x - k)
if prev is not None and b and both is not None:
best = min(best, prev[b - 1] + both)
row[b] = best
return dp[op1][op2]Minimum Array Sum solution in JavaScript
function minArraySum(nums, k, op1, op2) {
const dp = Array.from({ length: op1 + 1 }, () => new Array(op2 + 1).fill(0));
for (const x of nums) {
const half = Math.ceil(x / 2);
let both = Infinity;
if (x >= k) both = Math.ceil((x - k) / 2);
if (half >= k) both = Math.min(both, half - k);
for (let a = op1; a >= 0; a--) {
for (let b = op2; b >= 0; b--) {
let best = dp[a][b] + x;
if (a > 0) best = Math.min(best, dp[a - 1][b] + half);
if (b > 0 && x >= k) best = Math.min(best, dp[a][b - 1] + x - k);
if (a > 0 && b > 0) best = Math.min(best, dp[a - 1][b - 1] + both);
dp[a][b] = best;
}
}
}
return dp[op1][op2];
}Common mistakes
- Rounding the halving down instead of up. 7 halves to 4, not 3.
- Always halving before subtracting. For x = 7 and k = 5 that makes the subtraction illegal and misses the better result 1.
- Checking x ≥ k against the original value when the subtraction happens after halving.
- Iterating the budgets upward in a single table, which lets one element use the same operation twice.
- Using a greedy rule like "halve the largest values first", which fails when the subtraction would have been worth more on those values.
What interviewers look for
Start by saying why greedy is risky here: two operations interact and the ≥ k condition depends on order. Then frame it as a knapsack with two capacities. Interviewers want to hear the state definition stated precisely ("best sum of the first i elements using at most a and b operations") before you code.
Spend a minute on the "both" option and the order question, and use a tiny example like x = 7, k = 5 to show you checked it. Finish by mentioning the downward iteration and the resulting O(op1 · op2) memory.
Follow-up questions
Is there a greedy solution?
There is a sort-based greedy that works by carefully assigning the largest values to "both", then handling a middle band where the choice depends on parity and the k threshold, but it needs a delicate case analysis to be correct. With n ≤ 100 the DP is simpler to get right, and that tradeoff is worth saying out loud.
What if each index could be halved any number of times?
Then the options per element are no longer fixed. Repeated halving has diminishing returns, so you would use a max-heap of the current gain from one more halving and pop the best gain op1 times, combining that with the subtraction choice. The DP would need an extra dimension for how many halvings each element gets.
How would you also return which operations to apply?
Keep the full 3D table dp[i][a][b] (or a parent pointer per state) and walk back from dp[n][op1][op2], checking at each element which of the four options produced the stored value. That costs O(n · op1 · op2) memory instead of O(op1 · op2).
Companies that ask Minimum Array Sum
Minimum Array Sum is tagged by 87 companies in our interview dataset. The score shows how often it comes up at each company.
- Ansys100%
- Buffer100%
- Fiserv100%
- Sonos98%
- Project4496%
- Iqvia94%
- Payactiv94%
- Cummins93%
- Sambanova Systems88%
- Freelancercom87%
- UPS86%
- Offerup84%
- Equipmentshare83%
- Fujitsu83%
- Consensys82%
- Eightfold AI81%
- Infinera81%
- Adevinta79%
- Booz Allen Hamilton79%
- Darktrace79%
- Adesso79%
- Lendingclub77%
- Angi75%
- Daimler75%
and 63 more.
Practice next
Get live help in the real interview
Working solutions in real time during your actual interview. Invisible to screensharing.
Start Free TrialNo credit card required