📌  相关文章
📜  最小化给定数组之间相应索引处不相等元素的数量(1)

📅  最后修改于: 2023-12-03 15:40:16.135000             🧑  作者: Mango

最小化数组中相应索引处不相等元素的数量

给定两个长度相等的整数数组 nums1nums2,请你考虑将 nums2 打乱并以任意顺序排列,以使它最小化 nums1[i]nums2[i] 不相等的数量。

请你返回最小化上述数量后的任意排列方式。

示例 1

输入: nums1 = [2,1,2,1], nums2 = [1,2,1,2] 输出: [2,1,2,1] 解释: 通过打乱 nums2,可以找到一个相等的数组 [2,1,2,1]。

示例 2

输入: nums1 = [1,2,3,4], nums2 = [2,4,1,3] 输出: [2,1,3,4]

解题思路

题目要求将 nums2 重排以使得 nums1 和 nums2 相应位置上的数不相等的数量最小。我们可以将 nums2 排序,然后从小到大枚举 nums1 和 nums2 的每个数,尽量将二者各自的数配对。这样做可以确保相应位置的数值差最小。

具体来说,在枚举 nums1 和 nums2 的某个数时,记它们的下标分别为 i 和 j。如果 nums1[i] >= nums2[j],那么我们可以将 nums2[j] 与它前面的某个数配对。如果在 nums2 中不存在这样的前面的数,那么只能将 nums2[j] 与后面的某个数配对。为了使得配对后的结果尽量满足 nums1[i] 和 nums2[j] 不相等,我们选择 nums2[j] 的前面的那个数与 nums2[j] 进行配对。

对于 nums1 和 nums2 中剩下的未配对的元素,它们之间的配对与它们各自的配对可以是任意的,因为它们对答案贡献的「不相等的数量」都已经被前面的配对所覆盖了。

代码实现
class Solution:
    def minimumDeviation(self, nums1: List[int], nums2: List[int]) -> int:
        nums2 = [x if x % 2 == 0 else x * 2 for x in nums2] # 将 nums2 中所有奇数乘以 2
        sorted_nums2 = sorted(nums2, reverse=True)
        ans = float('inf')
        for i, x in enumerate(nums1):
            while sorted_nums2 and sorted_nums2[-1] < x: # nums2 中数不够用了,跳出循环
                sorted_nums2.pop()
            if not sorted_nums2: # 如果 nums2 中数不够用了,跳出循环
                break
            ans = min(ans, abs(sorted_nums2[-1] - x))
        return ans

代码解释:

  • 在枚举 nums1 的过程中,我们需要维护 nums2 的最大值,每次贪心地将 nums1[i] 与 nums2 中最小的那个数进行配对即可。
  • 由于所有的奇数都只能变为偶数,而偶数变化后的结果一定不会比变化前的结果更小,因此直接将所有的奇数都乘以 2,可以确保结果不劣(即不更劣)。