2918. Minimum Equal Sum of Two Arrays After Replacing Zeros
Problem Description
You have two arrays nums1
and nums2
that contain positive integers. However, these arrays may also contain zeros.
Your task is to replace all zeros in both arrays with strictly positive integers (numbers greater than 0). The goal is to make the sum of all elements in nums1
equal to the sum of all elements in nums2
after the replacements.
You need to find the minimum possible sum that both arrays can have after replacing all zeros. If it's impossible to make the sums equal, return -1
.
Key Points:
- Each
0
must be replaced with at least1
(or any positive integer) - All zeros must be replaced (you cannot leave any zeros)
- After replacement,
sum(nums1)
must equalsum(nums2)
- You want the minimum possible equal sum
Example scenarios:
- If
nums1 = [3, 2, 0, 1, 0]
andnums2 = [6, 5, 0]
, you could replace the zeros to make both sums equal - The minimum sum would be achieved by replacing each
0
with1
initially and adjusting as needed - If one array has no zeros and already has a larger sum than the other array could possibly achieve, it's impossible to make them equal
Intuition
To find the minimum equal sum, we need to think about the constraints each array has. Since we must replace all zeros with at least 1
, each array has a minimum possible sum it can achieve.
For any array, the minimum sum occurs when we replace all zeros with 1
. So for nums1
, the minimum possible sum is sum(non-zero elements) + count(zeros)
. The same applies to nums2
.
Let's call these minimum sums s1
and s2
. Now we have three cases to consider:
-
If
s1 = s2
: Both arrays reach the same sum when replacing zeros with1
s. This is the minimum possible equal sum, so we returns1
. -
If
s1 < s2
: Arraynums1
needs to reach at leasts2
. This is only possible ifnums1
has zeros that we can replace with values larger than1
. Ifnums1
has at least one zero, we can replace it with a larger number to matchs2
. Ifnums1
has no zeros, it's stuck at its current sum and can never reachs2
, so we return-1
. -
If
s1 > s2
: This is symmetric to case 2, just with the arrays swapped.
The key insight is that once we calculate the minimum possible sums, we only need to check if the array with the smaller minimum sum has the flexibility (contains zeros) to reach the larger minimum sum. The answer will always be the larger of the two minimum sums if it's achievable, or -1
if it's impossible.
Learn more about Greedy patterns.
Solution Approach
The implementation follows a clean and efficient approach based on our case analysis:
-
Calculate minimum possible sums:
- For
nums1
:s1 = sum(nums1) + nums1.count(0)
- For
nums2
:s2 = sum(nums2) + nums2.count(0)
This treats each zero as if it were replaced by
1
, giving us the minimum achievable sum for each array. - For
-
Normalize the comparison: To avoid duplicate logic, we ensure
s1 ≤ s2
by recursively calling the function with swapped parameters ifs1 > s2
:if s1 > s2: return self.minSum(nums2, nums1)
This clever trick means we only need to handle cases where
s1 ≤ s2
. -
Handle the equal case: If
s1 == s2
, both arrays already achieve the same minimum sum, so we returns1
. -
Handle the unequal case (
s1 < s2
):- We need
nums1
to reachs2
- Check if
nums1
has any zeros:nums1.count(0) == 0
- If no zeros exist in
nums1
, it cannot increase its sum, so return-1
- If zeros exist, we can replace them with values larger than
1
to reachs2
, so returns2
- We need
The solution elegantly handles all cases in just a few lines by leveraging the recursive swap to reduce the problem to a single comparison direction. The time complexity is O(n + m)
where n
and m
are the lengths of the arrays, as we only need to traverse each array once to calculate sums and count zeros.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example to illustrate the solution approach.
Example: nums1 = [3, 2, 0, 1, 0]
and nums2 = [6, 5, 0]
Step 1: Calculate minimum possible sums
-
For
nums1
:- Sum of non-zero elements:
3 + 2 + 1 = 6
- Count of zeros:
2
- Minimum possible sum
s1 = 6 + 2 = 8
(replacing each 0 with 1)
- Sum of non-zero elements:
-
For
nums2
:- Sum of non-zero elements:
6 + 5 = 11
- Count of zeros:
1
- Minimum possible sum
s2 = 11 + 1 = 12
(replacing the 0 with 1)
- Sum of non-zero elements:
Step 2: Compare the minimum sums
- We have
s1 = 8
ands2 = 12
- Since
s1 < s2
, we proceed without swapping
Step 3: Check if the smaller sum can reach the larger sum
nums1
needs to reach sum12
(currently minimum is8
)- Does
nums1
have zeros? Yes, it has 2 zeros - Since
nums1
has zeros, we can replace them with values larger than 1 - Instead of replacing both zeros with 1 (giving sum 8), we can replace them with larger values:
- Replace the two zeros with
1
and5
, or2
and4
, or3
and3
- Any of these gives us:
3 + 2 + 1 + (values summing to 6) = 12
- Replace the two zeros with
Step 4: Return the result
- Since
nums1
can reachs2 = 12
, return12
The final arrays could be:
nums1 = [3, 2, 3, 1, 3]
(sum = 12)nums2 = [6, 5, 1]
(sum = 12)
Counter-example (impossible case):
If nums1 = [3, 2, 4]
(no zeros) and nums2 = [1, 0, 0]
:
s1 = 3 + 2 + 4 = 9
(no zeros to replace)s2 = 1 + 2 = 3
(minimum with zeros replaced by 1)- Since
s1 > s2
, we'd swap and check ifnums2
can reach 9 nums2
has zeros, so it can increase from 3 to 9 by replacing the zeros with larger values- Return
9
Solution Implementation
1class Solution:
2 def minSum(self, nums1: List[int], nums2: List[int]) -> int:
3 # Calculate the minimum possible sum for each array
4 # Each 0 must be replaced with at least 1
5 min_sum1 = sum(nums1) + nums1.count(0)
6 min_sum2 = sum(nums2) + nums2.count(0)
7
8 # Swap arrays if first array has larger minimum sum (optimization)
9 if min_sum1 > min_sum2:
10 return self.minSum(nums2, nums1)
11
12 # If minimum sums are equal, this is the answer
13 if min_sum1 == min_sum2:
14 return min_sum1
15
16 # At this point, min_sum1 < min_sum2
17 # Check if nums1 can increase its sum to match min_sum2
18 # If nums1 has no zeros, it cannot increase its sum
19 if nums1.count(0) == 0:
20 return -1
21 else:
22 # nums1 has zeros, so it can increase to match min_sum2
23 return min_sum2
24
1class Solution {
2 /**
3 * Finds the minimum possible sum after replacing all zeros with positive integers
4 * such that both arrays have equal sums.
5 *
6 * @param nums1 First array of non-negative integers
7 * @param nums2 Second array of non-negative integers
8 * @return Minimum possible equal sum, or -1 if impossible
9 */
10 public long minSum(int[] nums1, int[] nums2) {
11 // Calculate minimum possible sum for nums1 (replacing 0s with 1s)
12 long sum1 = 0;
13 boolean hasZeroInNums1 = false;
14
15 for (int num : nums1) {
16 // Track if nums1 contains any zeros
17 hasZeroInNums1 |= (num == 0);
18 // Add the number itself, or 1 if it's zero (minimum positive integer)
19 sum1 += Math.max(num, 1);
20 }
21
22 // Calculate minimum possible sum for nums2 (replacing 0s with 1s)
23 long sum2 = 0;
24 for (int num : nums2) {
25 // Add the number itself, or 1 if it's zero
26 sum2 += Math.max(num, 1);
27 }
28
29 // If sum1 > sum2, swap the arrays by recursively calling with reversed parameters
30 if (sum1 > sum2) {
31 return minSum(nums2, nums1);
32 }
33
34 // If sums are already equal, return the common sum
35 if (sum1 == sum2) {
36 return sum1;
37 }
38
39 // At this point, sum1 < sum2
40 // We can only increase sum1 if it has zeros (by replacing them with values > 1)
41 // If nums1 has zeros, we can make sum1 equal to sum2
42 // Otherwise, it's impossible to make them equal
43 return hasZeroInNums1 ? sum2 : -1;
44 }
45}
46
1class Solution {
2public:
3 long long minSum(vector<int>& nums1, vector<int>& nums2) {
4 // Calculate the sum of nums1, treating 0s as 1s (minimum valid value)
5 long long sum1 = 0;
6 bool nums1HasZero = false;
7
8 for (int num : nums1) {
9 // Track if there's at least one zero in nums1
10 nums1HasZero |= (num == 0);
11 // Add the number to sum, but treat 0 as 1
12 sum1 += max(num, 1);
13 }
14
15 // Calculate the sum of nums2, treating 0s as 1s
16 long long sum2 = 0;
17 for (int num : nums2) {
18 sum2 += max(num, 1);
19 }
20
21 // Ensure sum1 <= sum2 by swapping if necessary
22 // This simplifies the logic by always handling the smaller sum first
23 if (sum1 > sum2) {
24 return minSum(nums2, nums1);
25 }
26
27 // If sums are already equal, return the common sum
28 if (sum1 == sum2) {
29 return sum1;
30 }
31
32 // At this point, sum1 < sum2
33 // We can only increase sum1 if nums1 has zeros (which can be replaced with values > 1)
34 // If nums1 has zeros, we can potentially match sum2; otherwise, it's impossible
35 return nums1HasZero ? sum2 : -1;
36 }
37};
38
1/**
2 * Finds the minimum possible sum after replacing zeros in two arrays
3 * @param nums1 - First array of non-negative integers
4 * @param nums2 - Second array of non-negative integers
5 * @returns The minimum equal sum possible, or -1 if impossible
6 */
7function minSum(nums1: number[], nums2: number[]): number {
8 // Calculate sum of first array, treating zeros as ones
9 let sum1: number = 0;
10 let hasZeroInNums1: boolean = false;
11
12 for (const num of nums1) {
13 if (num === 0) {
14 hasZeroInNums1 = true;
15 }
16 // Add the number itself if positive, otherwise add 1 (for zeros)
17 sum1 += Math.max(num, 1);
18 }
19
20 // Calculate sum of second array, treating zeros as ones
21 let sum2: number = 0;
22
23 for (const num of nums2) {
24 // Add the number itself if positive, otherwise add 1 (for zeros)
25 sum2 += Math.max(num, 1);
26 }
27
28 // If sum1 is greater, swap the arrays and recalculate
29 if (sum1 > sum2) {
30 return minSum(nums2, nums1);
31 }
32
33 // If sums are already equal, return the sum
34 if (sum1 === sum2) {
35 return sum1;
36 }
37
38 // If sum1 < sum2, we can only increase sum1 if it has zeros
39 // Return sum2 if nums1 has zeros (can be increased), otherwise impossible
40 return hasZeroInNums1 ? sum2 : -1;
41}
42
Time and Space Complexity
The time complexity is O(n + m)
, where n
and m
are the lengths of the arrays nums1
and nums2
, respectively. This is because:
sum(nums1)
takesO(n)
time to traverse all elements innums1
nums1.count(0)
takesO(n)
time to count zeros innums1
sum(nums2)
takesO(m)
time to traverse all elements innums2
nums2.count(0)
takesO(m)
time to count zeros innums2
- The recursive call
self.minSum(nums2, nums1)
whens1 > s2
doesn't add to the complexity since it only swaps the arguments and the same operations are performed once - Overall:
O(n) + O(n) + O(m) + O(m) = O(n + m)
The space complexity is O(1)
. The algorithm only uses a constant amount of extra space:
- Variables
s1
ands2
store single integer values - The recursive call has a maximum depth of 1 (it only recurses once to swap arguments if needed)
- No additional data structures are created that scale with input size
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Counting zeros multiple times inefficiently
A common mistake is calling count(0)
multiple times on the same array, which unnecessarily traverses the array multiple times.
Pitfall Code:
min_sum1 = sum(nums1) + nums1.count(0)
min_sum2 = sum(nums2) + nums2.count(0)
# Later in the code...
if nums1.count(0) == 0: # Counting zeros again!
return -1
Solution: Store the zero counts in variables to avoid redundant iterations:
zeros1 = nums1.count(0)
zeros2 = nums2.count(0)
min_sum1 = sum(nums1) + zeros1
min_sum2 = sum(nums2) + zeros2
# Later use the stored value
if zeros1 == 0:
return -1
2. Forgetting that both arrays might have no zeros
A subtle pitfall is not considering the case where both arrays have no zeros but different sums. In this scenario, neither array can adjust its sum.
Pitfall Thinking: Only checking if one array has no zeros when trying to match sums.
Solution:
The recursive swap handles this elegantly, but you should understand that when min_sum1 < min_sum2
and nums1
has no zeros, it's impossible. Similarly, if the roles were reversed (before the swap), nums2
having no zeros would make it impossible.
3. Integer overflow concerns (in other languages)
While Python handles large integers gracefully, in languages like Java or C++, summing large arrays could cause overflow.
Solution for other languages: Use long/int64 data types:
long minSum1 = 0; for (int num : nums1) { minSum1 += num; }
4. Misunderstanding the problem constraints
A critical pitfall is thinking you can choose which zeros to replace or leave some zeros unchanged. The problem requires ALL zeros to be replaced with positive integers.
Wrong interpretation: "Maybe I can leave some zeros as they are if it helps minimize the sum"
Correct understanding: Every single zero MUST be replaced with at least 1 (or higher if needed to match sums).
Which of the tree traversal order can be used to obtain elements in a binary search tree in sorted order?
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!