2918. Minimum Equal Sum of Two Arrays After Replacing Zeros
Problem Description
In this problem, we are provided with two arrays, nums1
and nums2
, each containing positive integers. However, both arrays may contain zeros, and we need to find a way to replace these zeros with positive integers. Our goal is to ensure that after the replacements, the sum of the integers in both arrays is the same.
The question then is: What is the minimum equal sum we can achieve after replacing all zeros with strictly positive integers? If it is not possible to make the sums of both arrays equal by replacing zeros, the function should return -1
.
It's a problem that demands a careful examination of the sums of arrays and the zeros they contain to find a method to balance the sums with minimum changes.
Intuition
To approach the problem, we first handle the zeros in a straightforward way. We consider replacing each zero with 1, as this is the smallest strictly positive integer. This gives us a baseline sum for each array.
Let s1
and s2
be the sums of nums1
and nums2
respectively when each zero is treated as 1. Based on these sums, we can reason about the possible scenarios:
- If
s1
equalss2
, we already have equality and do not need to replace any zeros with larger numbers, so the baseline sum is the answer. - If
s1
is less thans2
, and there are zeros innums1
, we can increase the sum ofnums1
by replacing zeros with numbers larger than 1 to matchs2
. In this case, sinces2
is larger, it is our target, and we returns2
because it represents the minimum equal sum we can achieve. - Conversely, if
s1
is more thans2
, we swap the roles ofnums1
andnums2
to apply the above reasoning. - If
s1
is less thans2
, butnums1
has no zeros, we cannot increase the sum ofnums1
to matchs2
. Thus, it is impossible to make the sums equal and we return-1
.
This way, we identify the minimum sum after replacements that makes both arrays' sums equal, or determine the impossibility of such an operation.
Solution Approach
The solution approach is to first calculate the sums of the arrays while treating all zeros as ones. This calculation is straightforward and can be done using the built-in sum
function in Python, along with the count
method to account for the zeros. The following code calculates these sums for nums1
and nums2
:
s1 = sum(nums1) + nums1.count(0)
s2 = sum(nums2) + nums2.count(0)
Once the sums are calculated, we compare them to decide the next steps:
- If
s1
is greater thans2
, we have a helper function,self.minSum
, that we call with the arrays swapped. This is an example of recursion that helps us reduce the problem to a single direction wheres1
is less than or equal tos2
, ensuring a more straightforward decision process:
if s1 > s2: return self.minSum(nums2, nums1)
- If the sums are already equal (
s1 == s2
), we have achieved the goal of equal sums with minimum effort, merely by treating zeros as ones. The baseline sums1
(ors2
, since they are equal now) is the minimum sum we can achieve, so we return it:
if s1 == s2: return s1
- In the case that
s1
is less thans2
, we have two scenarios. If there are zeros innums1
, we can replace them with numbers greater than one to match the sums2
. Therefore, we returns2
which is the target sum:
if nums1.count(0) != 0: return s2
- Finally, if there are no zeros in
nums1
, it implies we cannot adjust the sum ofnums1
to matchs2
, making it impossible for both array sums to be equal, and we return-1
:
else: return -1
By considering these conditions and applying the recursive step, the algorithm ensures minimum modifications are made to achieve equal sums, or it correctly identifies when the task is impossible. The use of simple built-in functions and conditional logic, along with recursion, forms the core of this solution, eliminating the need for complex data structures or patterns.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Consider the arrays nums1 = [0, 2, 3]
and nums2 = [1, 0, 4, 0]
.
-
We start by treating all zeros in
nums1
andnums2
as ones and calculate their sums.- For
nums1
: The sum is1 (replacing 0) + 2 + 3 = 6
. - For
nums2
: The sum is1 + 1 (replacing 0) + 4 + 1 (replacing 0) = 7
. s1
becomes 6 ands2
becomes 7.
- For
-
We compare
s1
ands2
. Sinces1
is less thans2
, we proceed without swapping the arrays. -
Because
s1
(sum ofnums1
) is less thans2
(sum ofnums2
), we check if there are zeros present innums1
that we can replace to match the sums2
. Indeed,nums1
has one zero. -
We can replace the zero in
nums1
with a positive integer that will raise the sum ofnums1
to matchs2
. Sinces2
is 7, and the current sum ofnums1
is 6, we can replace the zero with any number greater than 1 to meet or exceed the sum ofnums2
. For minimal increment, we can choose to replace zero with the smallest number greater than 1, which is 2. It is nownums1 = [2, 2, 3]
. -
After replacement, the sum of
nums1
is now2 + 2 + 3 = 7
, which matchess2
. -
Since we can match the sums by replacing zeros with strictly positive integers, we return
s2
. Here, the minimum equal sum we achieve is 7.
According to this logic, if nums1
had no zeros but still had a smaller sum than nums2
, we would return -1
, indicating it's not possible to match the sums.
Now, let's break down the steps according to the code snippets provided in the solution approach:
- Step 1 corresponds to the initial calculations:
s1 = sum(nums1) + nums1.count(0) # s1 = 6
s2 = sum(nums2) + nums2.count(0) # s2 = 7
- Since
s1 < s2
, we do not swapnums1
andnums2
, and the first recursive call is skipped. - Checking
s1 == s2
would skip the second condition in this case since they are not equal. - In the third condition, we evaluate
if nums1.count(0) != 0:
. Becausenums1
contains a zero, we returns2
(7), which represents the minimum equal sum we can achieve after replacements. - There is no need to execute the last condition
else: return -1
since we did not return-1
.
if nums1.count(0) != 0: return s2 # returns 7
The given example demonstrates how the solution approach is applied to find the minimum equal sum after replacing all zeros with strictly positive integers or determining when it's not possible to match the sums.
Solution Implementation
1class Solution:
2 def minSum(self, nums1: List[int], nums2: List[int]) -> int:
3 # Calculate the sum of elements in each list. The sum includes an extra 1 for each zero found in the list
4 sum_nums1 = sum(nums1) + nums1.count(0)
5 sum_nums2 = sum(nums2) + nums2.count(0)
6
7 # If the sum of the first list is greater than the second, recursively call minSum with reversed lists
8 if sum_nums1 > sum_nums2:
9 return self.minSum(nums2, nums1)
10
11 # If the sums are equal, return the sum (since that is the minimum sum after replacing zeros)
12 if sum_nums1 == sum_nums2:
13 return sum_nums1
14
15 # If there are no zeros in the first list, it's not possible to make the sums equal, return -1
16 # Otherwise, return the sum of the second list as it is the smaller sum
17 return -1 if nums1.count(0) == 0 else sum_nums2
18
1class Solution {
2
3 /**
4 * Computes the minimum sum possible between two given arrays after making sure
5 * that none of the elements in the arrays are less than one.
6 * It returns -1 if it is impossible to make both sums equal without the use of zeros.
7 *
8 * @param nums1 the first array of integers
9 * @param nums2 the second array of integers
10 * @return the minimum sum possible or -1 if it can't be done
11 */
12 public long minSum(int[] nums1, int[] nums2) {
13 long sum1 = 0; // Initialize sum for the first array
14 long sum2 = 0; // Initialize sum for the second array
15 boolean hasZero = false; // Flag to check for presence of zero in nums1
16
17 // Iterate over the first array
18 for (int value : nums1) {
19 hasZero |= value == 0; // Set the flag if zero is found
20 sum1 += Math.max(value, 1); // Ensure that each value contributes at least 1 to the sum
21 }
22
23 // Iterate over the second array
24 for (int value : nums2) {
25 sum2 += Math.max(value, 1); // Ensure that each value contributes at least 1 to the sum
26 }
27
28 // If the sum of the first array is greater, call the function again with reversed parameters
29 if (sum1 > sum2) {
30 return minSum(nums2, nums1);
31 }
32
33 // If the sums are equal, return the sum of the first array
34 if (sum1 == sum2) {
35 return sum1;
36 }
37
38 // If there is a zero in the first array and the sums are not equal, returning the sum of the
39 // second array is valid; otherwise, return -1 as it is impossible to make sums equal.
40 return hasZero ? sum2 : -1;
41 }
42}
43
1class Solution {
2public:
3 // Function to calculate the minimum sum of modified arrays such that their sums are equal
4 long long minSum(vector<int>& nums1, vector<int>& nums2) {
5 long long sumNums1 = 0; // Sum of elements in nums1
6 long long sumNums2 = 0; // Sum of elements in nums2
7 bool hasZero = false; // Flag to check if nums1 contains a zero
8
9 // Calculate the sum for nums1, replacing zeros with ones (as min(x, 1) ensures)
10 for (int num : nums1) {
11 hasZero |= num == 0; // Update the flag if there's a zero in the array
12 sumNums1 += std::max(num, 1); // Add the maximum of the number and 1 to the sum
13 }
14
15 // Calculate the sum for nums2 in a similar way, replacing zeros with ones
16 for (int num : nums2) {
17 sumNums2 += std::max(num, 1);
18 }
19
20 // If sum of nums1 is greater than sum of nums2, we should calculate minSum in the opposite order
21 if (sumNums1 > sumNums2) {
22 return minSum(nums2, nums1);
23 }
24
25 // If sums are equal, return the sum of nums1 (which is now confirmed to be the smaller sum)
26 if (sumNums1 == sumNums2) {
27 return sumNums1;
28 }
29
30 // If there's a zero in nums1 and the sums are not equal, it's impossible to equalize the sums
31 // Since we can't lower the sum of the other array, hence we return -1.
32 // If there is no zero, we can return the sum of the second array since it's larger.
33 return hasZero ? sumNums2 : -1;
34 }
35};
36
1/**
2 * Calculates the minimal sum of two arrays after ensuring that all elements are at least 1.
3 * If an array contains a zero, it is possible to swap arrays to minimize the sum.
4 *
5 * @param {number[]} nums1 First array of numbers.
6 * @param {number[]} nums2 Second array of numbers.
7 * @returns {number} The minimal sum or -1 if it's not possible to equalize sums with the given conditions.
8 */
9function minSum(nums1: number[], nums2: number[]): number {
10 let sum1 = 0;
11 let sum2 = 0;
12 let containsZero = false;
13
14 // Calculate sum for nums1 and flag if zero is found
15 for (const number of nums1) {
16 if (number === 0) {
17 containsZero = true;
18 }
19 sum1 += Math.max(number, 1);
20 }
21
22 // Calculate sum for nums2
23 for (const number of nums2) {
24 sum2 += Math.max(number, 1);
25 }
26
27 // Recursive call to swap nums1 and nums2 if sum1 is greater than sum2
28 if (sum1 > sum2) {
29 return minSum(nums2, nums1);
30 }
31
32 // If sums are equal, return the calculated sum
33 if (sum1 === sum2) {
34 return sum1;
35 }
36
37 // If contains a zero, we can swap to possibly minimize sum, otherwise return -1 as it's not possible
38 return containsZero ? sum2 : -1;
39}
40
Time and Space Complexity
Time Complexity
The time complexity of the code can be broken down as follows:
- Calculating sum of
nums1
andnums2
requires traversing both arrays, which costsO(n)
andO(m)
respectively, wheren
is the length ofnums1
andm
is the length ofnums2
. - Counting the zeroes in
nums1
andnums2
withnums1.count(0)
andnums2.count(0)
also takesO(n)
andO(m)
time respectively. - The recursive call
self.minSum(nums2, nums1)
only happens ifs1 > s2
. If multiple invocations occur, the process will still not exceedO(n + m)
because the sum and count operations are repeated once for each list. - The
if
comparisons are constant time operations,O(1)
.
Aggregating all these costs, the total time complexity is O(n + m)
because we are summing separate linear terms associated with each list.
Space Complexity
- The space complexity is
O(1)
as no additional space that grows with the input size is used. Variabless1
ands2
use constant space, and the recursive call does not exceed a single level of stack space since it's a direct swap with no further recursion.
The three-steps of Depth First Search are:
- Identify states;
- Draw the state-space tree;
- DFS on the state-space tree.
Recommended Readings
LeetCode 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 we
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 algomonster s3 us east 2 amazonaws com recursion jpg You first
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!