leet-code/src/main/java/leetcode/editor/cn/MinimumAbsoluteSumDifference.java
huangge1199@hotmail.com e6f67f887d 1818:绝对差值和
2021-07-14 20:11:32 +08:00

132 lines
4.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//给你两个正整数数组 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
//
//
//
//
// 示例 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
//
//
//
//
// 提示:
//
//
// n == nums1.length
// n == nums2.length
// 1 <= n <= 105
// 1 <= nums1[i], nums2[i] <= 105
//
// Related Topics 贪心 数组 二分查找 有序集合
// 👍 74 👎 0
package leetcode.editor.cn;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
//1818:绝对差值和
class MinimumAbsoluteSumDifference {
public static void main(String[] args) {
//测试代码
Solution solution = new MinimumAbsoluteSumDifference().new Solution();
}
//力扣代码
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int minAbsoluteSumDiff(int[] nums1, int[] nums2) {
final int MOD = 1000000007;
//创建 nums1 副本 并排序
int[] temp = Arrays.copyOf(nums1, nums1.length);
Arrays.sort(temp);
//求解 minDif 数组
int len = nums1.length;
int[] minDif = new int[len];
for (int i = 0; i < len; i++) {
int[] arr = leftright(temp, nums2[i]);
if (nums2[i] - temp[arr[0]] < temp[arr[1]] - nums2[i])
minDif[i] = temp[arr[0]];
else
minDif[i] = temp[arr[1]];
}
//寻找合适的元素替换nums1中的元素
int index = 0;
int max = 0;
for (int i = 0; i < len; i++) {
int dif = Math.abs(nums1[i] - nums2[i]) - Math.abs(minDif[i] - nums2[i]);
if (dif > max) {
index = i;
max = dif;
}
}
nums1[index] = minDif[index];
//累加和
int sum = 0;
for (int i = 0; i < len; i++)
sum = (sum + Math.abs(nums1[i] - nums2[i])) % MOD;
return sum;
}
//二分查找
public int[] leftright(int[] arr, int value) {
int left = 0;
int right = arr.length - 1;
int[] result = new int[2];
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == value) {
result[0] = result[1] = mid;
return result;
} else if (arr[mid] < value)
left = mid + 1;
else
right = mid - 1;
}
result[0] = left > 0 ? left - 1 : 0;
result[1] = right < arr.length - 1 ? right + 1 : arr.length - 1;
return result;
}
}
//leetcode submit region end(Prohibit modification and deletion)
}