leetcode
leetcode 2451 ~ 2500
数组的最小相等和

数组的最小相等和

难度:

标签:

题目描述

You are given two arrays nums1 and nums2 consisting of positive integers.

You have to replace all the 0's in both arrays with strictly positive integers such that the sum of elements of both arrays becomes equal.

Return the minimum equal sum you can obtain, or -1 if it is impossible.

 

Example 1:

Input: nums1 = [3,2,0,1,0], nums2 = [6,5,0]
Output: 12
Explanation: We can replace 0's in the following way:
- Replace the two 0's in nums1 with the values 2 and 4. The resulting array is nums1 = [3,2,2,1,4].
- Replace the 0 in nums2 with the value 1. The resulting array is nums2 = [6,5,1].
Both arrays have an equal sum of 12. It can be shown that it is the minimum sum we can obtain.

Example 2:

Input: nums1 = [2,0,2,0], nums2 = [1,4]
Output: -1
Explanation: It is impossible to make the sum of both arrays equal.

 

Constraints:

  • 1 <= nums1.length, nums2.length <= 105
  • 0 <= nums1[i], nums2[i] <= 106

代码结果

运行时间: 55 ms, 内存: 32.0 MB


/*
 * 思路:
 * 1. 使用流计算数组的非零元素和与零的数量。
 * 2. 计算两个数组和的差值与零的数量。
 * 3. 返回最小的相等和或-1。
 */

import java.util.Arrays;

public int minEqualSumStream(int[] nums1, int[] nums2) {
    int sum1 = Arrays.stream(nums1).filter(num -> num != 0).sum();
    int sum2 = Arrays.stream(nums2).filter(num -> num != 0).sum();
    long zeros1 = Arrays.stream(nums1).filter(num -> num == 0).count();
    long zeros2 = Arrays.stream(nums2).filter(num -> num == 0).count();
    long totalZeros = zeros1 + zeros2;
    int diff = Math.abs(sum1 - sum2);
    if (totalZeros < diff) return -1;
    return Math.max(sum1, sum2) + diff;
}

解释

方法:

这个题解的核心思路是首先计算每个数组中除零外所有元素的和,并加上零的个数,因为零至少需要被替换成1来使得和有效。这样,对于每个数组,计算的结果是如果所有的零被替换成1后数组的最小可能和。然后检查两个计算结果a和b。如果其中一个数组的和(假设为a)小于另一个数组的和(假设为b),同时第一个数组中不包含0(即无法通过增加零的值来调整总和),则返回-1,表示无法通过任何正整数替换0使两数组和相等。如果不是这种情况,返回a和b中的较大值,因为这就是将所有零替换为1后,能使得两数组和相等的最小值。

时间复杂度:

O(n + m)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么题解中将0至少替换为1来计算最小可能和,考虑到替换值可以是任意正整数,是否有其他替换策略会导致更优的结果?
题解中将0替换为1是为了计算两个数组在所有零至少被替换后的最小可能和。理论上,替换值可以是任意正整数,但是如果替换为1以外的其他值,虽然可以增加总和,使得两数组和更接近或相等,但这并不会影响最小可能和的初步计算结果。题解的目的是找到一个基线(即所有零至少替换为1的情况),确保两数组可以达到的最小和相等。选择1是因为它是最小的正整数,确保计算得到的和是最小可能的。
🦆
题解提到如果一个数组的和小于另一个数组的和且没有0可以替换,将返回-1。在何种情况下两数组的和差异过大使得即使替换所有0也无法使和相等?
如果两个数组的和之间存在差异,并且和较小的数组中不包含0,则即使将和较大的数组中的所有0替换为任意正整数,也无法使两数组的和相等。例如,如果一个数组的和为5,另一个为10,并且和为5的数组中没有0,那么无论如何替换和为10的数组中的0,都无法减少其总和,因此无法使两数组和相等。
🦆
题解中使用了max(a, b)来确定最小相等和,如果数组中的零较多,这种方法是否总是有效?换句话说,是否存在可以通过增加零的值来实现更小的相等和?
使用max(a, b)是基于假设所有的零都至少被替换成1的情况。在这种情况下,两个数组的最小相等和至少是a和b中的较大值。如果数组中的零较多,实际上可以选择更大的值来替换零,以达到两数组和相等的目的。然而,这不会影响最小可能和的计算,因为最小可能和基于所有零都至少替换成1的假设。如果两数组要实现相等和,他们的和至少需要达到a和b中的较大值,因为这是在最低替换条件下能达到的最小和。
🦆
在题解的实现中,使用了sum函数和count函数来计算和以及零的数量。是否存在一种方法可以在单次遍历中完成这两项任务,从而提高代码效率?
可以通过单次遍历数组来同时计算总和和零的数量,从而提高代码效率。在遍历过程中,对于每个元素,可以将其加到总和中,并同时检查是否为零来增加零的计数。这样可以避免对数组的多次遍历,减少运算时间。例如,可以使用一个循环,对数组中的每个元素进行检查和计算,这样只需要一次遍历就可以得到总和和零的数量。

相关问题