使数组中所有元素相等的最小操作数 II
难度:
标签:
题目描述
You are given two integer arrays nums1
and nums2
of equal length n
and an integer k
. You can perform the following operation on nums1
:
- Choose two indexes
i
andj
and incrementnums1[i]
byk
and decrementnums1[j]
byk
. In other words,nums1[i] = nums1[i] + k
andnums1[j] = nums1[j] - k
.
nums1
is said to be equal to nums2
if for all indices i
such that 0 <= i < n
, nums1[i] == nums2[i]
.
Return the minimum number of operations required to make nums1
equal to nums2
. If it is impossible to make them equal, return -1
.
Example 1:
Input: nums1 = [4,3,1,4], nums2 = [1,3,7,1], k = 3 Output: 2 Explanation: In 2 operations, we can transform nums1 to nums2. 1st operation: i = 2, j = 0. After applying the operation, nums1 = [1,3,4,4]. 2nd operation: i = 2, j = 3. After applying the operation, nums1 = [1,3,7,1]. One can prove that it is impossible to make arrays equal in fewer operations.
Example 2:
Input: nums1 = [3,8,5,2], nums2 = [2,4,1,6], k = 1 Output: -1 Explanation: It can be proved that it is impossible to make the two arrays equal.
Constraints:
n == nums1.length == nums2.length
2 <= n <= 105
0 <= nums1[i], nums2[j] <= 109
0 <= k <= 105
代码结果
运行时间: 55 ms, 内存: 29.9 MB
/*
* 思路:
* 使用Java Stream处理:
* 1. 计算每个对应位置的差值。
* 2. 分别统计增加和减少的总次数。
* 3. 如果增加和减少的次数不等,则返回-1。
* 4. 如果k为0,且所有差值都为0,则返回0,否则返回-1。
* 5. 否则,返回总操作次数。总操作次数为增加或减少总次数的较大值(因为增加和减少应该相等)。
*/
import java.util.stream.IntStream;
public class Solution {
public int minOperations(int[] nums1, int[] nums2, int k) {
long[] counts = IntStream.range(0, nums1.length)
.mapToLong(i -> nums1[i] - nums2[i])
.filter(diff -> diff != 0)
.map(diff -> diff > 0 ? diff / k : -diff / k)
.toArray();
long add = 0, subtract = 0;
for (long count : counts) {
if (count > 0) subtract += count;
else add += -count;
}
return add == subtract ? (int)add : -1;
}
}
解释
方法:
题解的核心思想是首先计算两个数组中对应位置元素的差值,并检查这些差值是否能被k整除。若不能整除,则直接返回-1,因为不能通过指定操作使两数组相等。如果能整除,则计算每个位置需要的操作次数(差值除以k的商),并累加。特别地,对于所有正差值的累加总和(即需要增加的总次数),单独计算为变量ans。若总操作次数为0,说明两数组已相等,返回ans;否则返回-1。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在题解中,当差值不是k的倍数时直接返回-1而不考虑其他可能的操作组合来调整差值?
▷🦆
题解中提到`如果x > 0: ans += x // k`,这里为什么只对正差值累加操作次数,负差值的处理逻辑是什么?
▷🦆
题解的算法在处理`sum += x // k`时,是否考虑了累加的正负号对最终结果的影响?
▷🦆
在题解的代码中,`elif x: return -1`这个条件是在检查什么情况?如果k为0,为什么不能有任何非零差值?
▷