📅  最后修改于: 2023-12-03 15:41:33.373000             🧑  作者: Mango
给定一个整数数组 nums 和一个整数 K,找到要删除的最小子数组的大小,使得数组中大于 K 的元素数量等于小于等于 K 的元素的数量。
输入: nums = [4,3,2,5,6,7,8,1,9], K = 5
输出: 2
解释:
我们可以从数组中删除 [4,3],使得大于 K 的元素数量等于小于等于 K 的元素的数量,所以最小的子数组为 [4,3],大小为 2。
首先,我们需要知道大于和小于 K 的元素数量。我们可以用两个变量存储这些元素的数量。接着,我们需要遍历数组并计算当前子数组的大于和小于 K 的元素的数量。这可以通过在遍历数组时维护一个前缀和来实现。
具体地,我们定义一个变量 diff,它存储当前子数组大于 K 元素数量与小于等于 K 元素数量之间的差值。具体来说,diff 的值等于当前子数组大于 K 的元素数量减去小于等于 K 的元素数量。如果 diff 的值为 0,则当前子数组满足要求,可以计算子数组的长度并更新最小子数组的长度。
如果当前 diff 的值不为 0,则我们需要尝试移动左指针或右指针以减小当前子数组的大小。具体来说,我们要根据 diff 的符号和绝对值进行讨论:
最终,我们可以返回最小子数组的长度。
def min_subarray(nums: List[int], k: int) -> int:
left, right = 0, 0
gt, le = 0, 0
diff = 0
res = float('inf')
while right < len(nums):
if nums[right] > k:
gt += 1
diff += 1
else:
le += 1
diff -= 1
if diff == 0:
res = min(res, right - left + 1)
while diff > 0:
if nums[left] > k:
gt -= 1
diff -= 1
else:
le -= 1
diff += 1
left += 1
right += 1
return res if res < float('inf') else -1
其中,left 和 right 分别为左指针和右指针,gt 和 le 分别为大于和小于等于 K 的元素数量,diff 为当前子数组大于 K 的元素数量与小于等于 K 的元素数量之间的差值,res 为最小子数组的长度。
时间复杂度:O(n)。其中,n 为数组的长度。
空间复杂度:O(1)。我们只使用了常数个变量。