📌  相关文章
📜  通过重复删除 K 个数组元素来最大化清空给定数组的成本(1)

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

通过重复删除 K 个数组元素来最大化清空给定数组的成本

题目描述

给定一个包含 n 个整数的数组 nums ,你的任务是通过删除最多 k 次数组元素,使得剩下的元素中的最大值和最小值的差最小,最后返回最小的差。

示例
输入:nums = [1,3,4,9], k = 2
输出:2
解释:选择数字 1 和 4,剩余元素为 [3,9],最小差值为 9-3 = 6。选择数字 3 和 4,剩余元素为 [1,9],最小差值为 9-1 = 8。选择数字 1 和 3,剩余元素为 [4,9],最小差值为 9-4 = 5。因此最小差值为 2,即选择数字 1 和 4 。
思路

由题目可得,最小差的范围是 [0, max(nums)-min(nums)]。

对于每个差值 mid,我们需要找到最多可以删除 k 个元素的情况下,剩下元素中最大值和最小值的差小于等于 mid 是否成立。

我们可以利用二分查找来缩小差值的范围。对于 mid,我们在 nums 中找到所有比 mid 大的元素,尝试删除其中的 k 个,若剩余元素的最大值和最小值的差小于等于 mid,说明 mid 成立,否则 mid 不成立。

代码实现
class Solution:
    def minimumDifference(self, nums: List[int], k: int) -> int:
        nums.sort()
        n = len(nums)
        l, r = 0, nums[-1] - nums[0]
        while l <= r:
            mid = (r - l) // 2 + l
            cnt = 0
            j = 0
            for i in range(n):
                while j < n and nums[j] - nums[i] <= mid:
                    j += 1
                cnt += j - i - 1
            if cnt <= k:
                r = mid - 1
            else:
                l = mid + 1
        return l

代码中使用了二分查找的思想,时间复杂度为 O(n log(r-l))。

总结

本题采用二分查找的方法,实现较为简单,但需要借助数学知识推导出算法正确性,需要仔细思考。