Facebook Pixel

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 least 1 (or any positive integer)
  • All zeros must be replaced (you cannot leave any zeros)
  • After replacement, sum(nums1) must equal sum(nums2)
  • You want the minimum possible equal sum

Example scenarios:

  • If nums1 = [3, 2, 0, 1, 0] and nums2 = [6, 5, 0], you could replace the zeros to make both sums equal
  • The minimum sum would be achieved by replacing each 0 with 1 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
Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

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:

  1. If s1 = s2: Both arrays reach the same sum when replacing zeros with 1s. This is the minimum possible equal sum, so we return s1.

  2. If s1 < s2: Array nums1 needs to reach at least s2. This is only possible if nums1 has zeros that we can replace with values larger than 1. If nums1 has at least one zero, we can replace it with a larger number to match s2. If nums1 has no zeros, it's stuck at its current sum and can never reach s2, so we return -1.

  3. 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:

  1. 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.

  2. Normalize the comparison: To avoid duplicate logic, we ensure s1 ≤ s2 by recursively calling the function with swapped parameters if s1 > s2:

    if s1 > s2:
        return self.minSum(nums2, nums1)

    This clever trick means we only need to handle cases where s1 ≤ s2.

  3. Handle the equal case: If s1 == s2, both arrays already achieve the same minimum sum, so we return s1.

  4. Handle the unequal case (s1 < s2):

    • We need nums1 to reach s2
    • 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 reach s2, so return s2

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 Evaluator

Example 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)
  • 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)

Step 2: Compare the minimum sums

  • We have s1 = 8 and s2 = 12
  • Since s1 < s2, we proceed without swapping

Step 3: Check if the smaller sum can reach the larger sum

  • nums1 needs to reach sum 12 (currently minimum is 8)
  • 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 and 5, or 2 and 4, or 3 and 3
    • Any of these gives us: 3 + 2 + 1 + (values summing to 6) = 12

Step 4: Return the result

  • Since nums1 can reach s2 = 12, return 12

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 if nums2 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) takes O(n) time to traverse all elements in nums1
  • nums1.count(0) takes O(n) time to count zeros in nums1
  • sum(nums2) takes O(m) time to traverse all elements in nums2
  • nums2.count(0) takes O(m) time to count zeros in nums2
  • The recursive call self.minSum(nums2, nums1) when s1 > 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 and s2 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).

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which of the tree traversal order can be used to obtain elements in a binary search tree in sorted order?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More