Minimum Value to Get Positive Step by Step Sum
return smallest start values such that adding all the values in array are always positive
Minimum Value to Get Positive Step by Step Sum
Problem
You are given an array of integers nums. You choose a positive integer startValue.
We add the numbers of nums one by one from left to right, starting from startValue. This gives a step by step sum.
Return the minimum positive startValue such that the step by step sum is never less than 1.
Examples
Example 1
Input: nums = [-3,2,-3,4,2]
Output: 5
- With
startValue = 4, the sums are1, 3, 0, 4, 6. The third sum is0, which is less than 1. So4does not work. - With
startValue = 5, the sums are2, 4, 1, 5, 7. All sums are at least 1. So5works.
Example 2
Input: nums = [1,2]
Output: 1
- The start value must be positive, so the smallest choice is
1. - The sums are
2, 4. All are at least 1.
Example 3
Input: nums = [1,-2,-3]
Output: 5
- With
startValue = 5, the sums are6, 4, 1. All are at least 1. - With
startValue = 4, the last sum is0. So4does not work.
Constraints
1 <= nums.length <= 100-100 <= nums[i] <= 100
Main Idea
We use prefix sums. A prefix sum is the sum of the numbers from the start up to the current index.
- The step by step sum at index
iisstartValue + prefix[i]. - The hardest step is the one with the smallest prefix sum. Let us call it
minimal. - If the hardest step is at least 1, every other step is also at least 1.
- So we need:
startValue + minimal >= 1. - This gives:
startValue >= 1 - minimal.
Now there are two cases:
minimal > 0: Every prefix sum is already positive. We can use the smallest positive value, which is1.minimal <= 0: We must lift the smallest sum up to1. The answer is1 - minimal, which is1 + Math.abs(minimal).
Solution 1: Prefix Sum Array
var minStartValue = function (nums) {
let temp = [];
let tempsum = 0;
// build the prefix sums
for (let i = 0; i < nums.length; i++) {
temp.push(nums[i] + tempsum);
tempsum += nums[i];
}
// the smallest prefix sum is the hardest step
let minimal = Math.min(...temp);
// all prefix sums are positive
if (minimal > 0) {
return 1;
}
// lift the smallest sum up to 1
return 1 + Math.abs(minimal);
};
How the Code Works
- Step 1:
tempstores the prefix sums.tempsumis the running total. - Step 2: In each loop step, we push
nums[i] + tempsum, which is the prefix sum ati. Then we addnums[i]totempsum. - Step 3:
Math.min(...temp)finds the smallest prefix sum. - Step 4: If it is positive, we return
1. If not, we return1 + Math.abs(minimal).
Dry Run
Let us take nums = [-3, 2, -3, 4, 2].
i | nums[i] | Prefix sum |
|---|---|---|
0 | -3 | -3 |
1 | 2 | -1 |
2 | -3 | -4 |
3 | 4 | 0 |
4 | 2 | 2 |
- The smallest prefix sum is
-4. - The answer is
1 + 4 = 5.
Now let us take nums = [1, 2].
- The prefix sums are
1, 3. - The smallest is
1, which is greater than 0. So the answer is1.
Complexity
- Time Complexity:
O(n)nis the length of the array.- One loop builds the prefix sums, and
Math.minscans them once.
- Space Complexity:
O(n)- The
temparray storesnprefix sums.
- The
Tip:
Math.min(...temp)can fail for very large arrays. Heren <= 100, so it is safe.
Solution 2: Running Sum (O(1) Space)
We do not need to store all prefix sums. We only need the smallest one. So we keep a running sum and a minimal value.
var minStartValue = function (nums) {
let sum = 0;
let minimal = 0;
for (let num of nums) {
sum += num;
minimal = Math.min(minimal, sum);
}
return 1 - minimal;
};
How the Code Works
sumis the current prefix sum.minimalstarts at0. It keeps the smallest prefix sum seen so far.- If all prefix sums are positive,
minimalstays0, and the answer is1 - 0 = 1. - If some prefix sum is negative,
minimalis that negative number, and the answer is1 - minimal. - Starting
minimalat0handles both cases in one line, so we do not need anif.
Complexity
- Time Complexity:
O(n)- We go through the array once.
- Space Complexity:
O(1)- We use only two variables.
Comparison
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Prefix Sum Array | O(n) | O(n) |
| Running Sum | O(n) | O(1) |
Summary
- The step by step sum at each index is
startValue + prefix sum. - Only the smallest prefix sum matters, because it is the hardest step.
- We need
startValue + minimal >= 1, so the answer is1 - minimal. - If the smallest prefix sum is positive, the answer is
1. - The running sum version uses
minimal = 0at the start, so both cases are handled together. - Both solutions run in
O(n)time. The running sum version uses onlyO(1)space.