Skip to content

Latest commit

 

History

History

1818.Minimum Absolute Sum Difference

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

English Version

题目描述

给你两个正整数数组 nums1nums2 ,数组的长度都是 n

数组 nums1nums2绝对差值和 定义为所有 |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

解法

方法一:排序 + 二分查找

时间复杂度 O(nlogn),空间复杂度 O(n)。

Python3

class Solution:
    def minAbsoluteSumDiff(self, nums1: List[int], nums2: List[int]) -> int:
        diff = [abs(a - b) for a, b in zip(nums1, nums2)]
        mod = 10**9 + 7
        s = sum(diff)
        if s == 0:
            return 0
        nums1.sort()
        n = len(nums1)
        mx = 0
        for i, b in enumerate(nums2):
            d = diff[i]
            if d == 0:
                continue
            idx = bisect_left(nums1, b)
            a1 = a2 = 10**6
            if idx != n:
                a1 = nums1[idx]
            if idx:
                a2 = nums1[idx - 1]
            c = min(abs(b - a1), abs(b - a2))
            mx = max(mx, d - c)
        return (s - mx) % mod

Java

class Solution {
    private static final int MOD = (int) 1e9 + 7;

    public int minAbsoluteSumDiff(int[] nums1, int[] nums2) {
        int n = nums1.length;
        int[] diff = new int[n];
        int s = 0;
        for (int i = 0; i < n; ++i) {
            diff[i] = Math.abs(nums1[i] - nums2[i]);
            s = (s + diff[i]) % MOD;
        }
        if (s == 0) {
            return 0;
        }
        Arrays.sort(nums1);
        int mx = 0;
        for (int i = 0; i < n; ++i) {
            int d = diff[i];
            if (d == 0) {
                continue;
            }
            int b = nums2[i];
            int idx = search(nums1, b);
            int a1 = 1000000, a2 = 1000000;
            if (idx != n) {
                a1 = nums1[idx];
            }
            if (idx != 0) {
                a2 = nums1[idx - 1];
            }
            int c = Math.min(Math.abs(b - a1), Math.abs(b - a2));
            mx = Math.max(mx, d - c);
        }
        return (s - mx + MOD) % MOD;
    }

    private int search(int[] nums, int x) {
        int left = 0, right = nums.length;
        while (left < right) {
            int mid = (left + right) >> 1;
            if (nums[mid] >= x) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }
}

C++

class Solution {
public:
    int minAbsoluteSumDiff(vector<int>& nums1, vector<int>& nums2) {
        const int mod = 1e9 + 7;
        int n = nums1.size();
        vector<int> diff(n);
        int s = 0;
        for (int i = 0; i < n; ++i)
        {
            diff[i] = abs(nums1[i] - nums2[i]);
            s = (s + diff[i]) % mod;
        }
        if (s == 0) return 0;
        sort(nums1.begin(), nums1.end());
        int mx = 0;
        for (int i = 0; i < n; ++i)
        {
            int d = diff[i];
            if (d == 0) continue;
            int b = nums2[i];
            int idx = lower_bound(nums1.begin(), nums1.end(), b) - nums1.begin();
            int a1 = 1e6, a2 = 1e6;
            if (idx != n) a1 = nums1[idx];
            if (idx != 0) a2 = nums1[idx - 1];
            int c = min(abs(b - a1), abs(b - a2));
            mx = max(mx, d - c);
        }
        return (s - mx + mod) % mod;
    }
};

Go

func minAbsoluteSumDiff(nums1 []int, nums2 []int) int {
	mod := int(1e9) + 7
	n := len(nums1)
	diff := make([]int, n)
	s := 0
	for i := 0; i < n; i++ {
		diff[i] = abs(nums1[i] - nums2[i])
		s = (s + diff[i]) % mod
	}
	if s == 0 {
		return 0
	}
	sort.Ints(nums1)
	mx := 0
	for i, b := range nums2 {
		d := diff[i]
		if d == 0 {
			continue
		}
		idx := search(nums1, b)
		a1, a2 := 1000000, 1000000
		if idx != n {
			a1 = nums1[idx]
		}
		if idx != 0 {
			a2 = nums1[idx-1]
		}
		c := min(abs(b-a1), abs(b-a2))
		mx = max(mx, d-c)
	}
	return (s - mx + mod) % mod
}

func search(nums []int, x int) int {
	left, right := 0, len(nums)
	for left < right {
		mid := (left + right) >> 1
		if nums[mid] >= x {
			right = mid
		} else {
			left = mid + 1
		}
	}
	return left
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

...