leet-code/src/main/java/leetcode/editor/cn/MinimumAbsoluteSumDifference.java

132 lines
4.0 KiB
Java
Raw Normal View History

2021-07-14 20:11:32 +08:00
//给你两个正整数数组 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)
}