绝对差值和
难度:
标签:
题目描述
代码结果
运行时间: 104 ms, 内存: 29.4 MB
/*
* 思路:
* 1. 计算初始的绝对差值和。
* 2. 使用流操作来找到能够最小化绝对差值和的替换值。
* 3. 计算最大可能的差值减少。
* 4. 返回最小化的绝对差值和,对 10^9 + 7 取余。
*/
import java.util.Arrays;
public class MinAbsoluteSumDiffStream {
public int minAbsoluteSumDiff(int[] nums1, int[] nums2) {
int MOD = 1_000_000_007;
int[] sortedNums1 = Arrays.stream(nums1).sorted().toArray();
int initialDiff = Arrays.stream(nums1).map(i -> Math.abs(i - nums2[i])).sum() % MOD;
int maxDiffReduction = Arrays.stream(nums1).map(i -> {
int diff = Math.abs(nums1[i] - nums2[i]);
int closestIdx = Arrays.binarySearch(sortedNums1, nums2[i]);
if (closestIdx < 0) closestIdx = -(closestIdx + 1);
int minDiff = Integer.MAX_VALUE;
if (closestIdx < sortedNums1.length) minDiff = Math.min(minDiff, Math.abs(sortedNums1[closestIdx] - nums2[i]));
if (closestIdx > 0) minDiff = Math.min(minDiff, Math.abs(sortedNums1[closestIdx - 1] - nums2[i]));
return diff - minDiff;
}).max().getAsInt();
return (initialDiff - maxDiffReduction + MOD) % MOD;
}
}
解释
方法:
此题解的策略是首先计算出原始数组 nums1 和 nums2 之间的绝对差值和。然后尝试通过替换 nums1 中的每个元素来找到可能降低这个差值和的最大幅度。为了实现这一点,我们首先对 nums1 进行排序,以便于后续可以快速找到最接近 nums2 中任意元素 b 的 nums1 中的元素。对于 nums1 和 nums2 中的每个元素对 (a, b),我们计算原始差值 t = |a - b| 并累加到总和 ret 中。接着,使用二分搜索在排序后的 nums1 中查找最接近 b 的元素,计算如果替换了这个元素后的新差值 nt。我们记录下所有可能的替换中,减少的最大差值 r。最终答案即为原始差值和减去这个最大减少值 r,并对 10^9+7 取余。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在尝试最小化绝对差值和时,只考虑替换nums1中的单一元素,而不是多个元素?
▷🦆
在实施二分搜索查找最接近nums2中元素b的nums1元素时,如果有多个相同的最小差值,该如何选择?
▷🦆
题解中提到使用排序和二分搜索来优化查找过程,这种方法与直接遍历nums1中的每个元素相比,效率提升在哪里?
▷🦆
为什么在计算最大减少量r时,需要检查当前的差值t是否大于已记录的最大减少量r,这一步的逻辑依据是什么?
▷