一、题目描述
1.题目内容
给你两个正整数数组 nums1 和 nums2 ,数组的长度都是 n 。
数组 nums1 和 nums2 的绝对差值和定义为所有 |nums1[i] - nums2[i]|(0 <= i < n)的总和(下标从 0 开始)。
你可以选用 nums1 中的任意一个元素来替换 nums1 中的至多一个元素,以最小化绝对差值和。
在替换数组 nums1 中最多一个元素之后 ,返回最小绝对差值和。因为答案可能很大,所以需要对 109 + 7取余后返回。
|x| 定义为:
·如果 x >= 0 ,值为 x ,或者
·如果 x <= 0 ,值为 -x
2.题目示例
示例1
输入:nums1 = [1,7,5], nums2 = [2,3,5]
输出:3
解释:有两种可能的最优方案:
- 将第二个元素替换为第一个元素:[1,7,5] => [1,1,5] ,或者
- 将第二个元素替换为第三个元素:[1,7,5] => [1,5,5]
两种方案的绝对差值和都是 |1-2| + (|1-3| 或者 |5-3|) + |5-5| = 3
示例2
输入:nums1 = [2,4,6,8,10], nums2 = [2,4,6,8,10]
输出:0
解释:nums1 和 nums2 相等,所以不用替换元素。绝对差值和为 0
示例3
输入: nums1 = [1,10,4,4,2,7], nums2 = [9,3,5,1,7,4]
输出:20
解释:将第一个元素替换为第二个元素:[1,10,4,4,2,7] => [10,10,4,4,2,7]
绝对差值和为 |10-9| + |10-3| + |4-5| + |4-1| + |2-7| + |7-4| = 20
3.提示
n == nums1.length
n == nums2.length
1 <= n <= 105
1 <= nums1[i], nums2[i] <= 105
二、思路
排序数组二分查找。
对于每个元素进行查找,在nums1中查找与nums2相应数据最接近的元素,计算其差值,并与位置匹配的差值再作差,同时与已经记录的最大差值进行比较。最后得到的结果减去最大差值即为最终结果。
三、数据结构资料
请参考笔者总结的有关于本题所需使用的数据结构资料:
四、代码
class Solution
{
int modNumber = (int)1e9 + 7;
public int minAbsoluteSumDiff(int[] nums1, int[] nums2)
{
long longResult = 0;
int[] sorted = nums1.clone();
Arrays.sort(sorted);
int max = 0;
for(int i = 0; i < nums1.length; i++)
{
int temp0 = absSub(nums1[i], nums2[i]);
longResult += temp0;
int left = 0, right = nums1.length - 1;
while (left < right)
{
int mid = (left + right + 1) / 2;
if (sorted[mid] <= nums2[i])
{
left = mid;
}
else
{
right = mid - 1;
}
}
int temp1 = absSub(sorted[left], nums2[i]);
if(temp0 - temp1 > max)
{
max = temp0 - temp1;
}
if(left + 1 < nums1.length)
{
temp1 = absSub(sorted[left + 1], nums2[i]);
if(temp0 - temp1 > max)
{
max = temp0 - temp1;
}
}
}
longResult -= max;
int result = (int)(longResult % modNumber);
return result;
}
public static int absSub(int a, int b)
{
if(a > b)
{
return a - b;
}
else
{
return b - a;
}
}
}
五、复杂度分析
时间复杂度O(nlogn)
空间复杂度O(n)
执行用时 | 时间击败比例 | 内存消耗 | 内存击败比例 |
---|---|---|---|
63ms | 68% | 56.4MB | 6% |