3356. 零数组变换 II - 力扣(LeetCode)
class Solution:
def minZeroArray(self, nums: List[int], queries: List[List[int]]) -> int:
# 3355. 零数组变换 I
def check(k: int) -> bool:
# 差分数组(比原数组多1)
diff = [0] * (len(nums) + 1)
for l, r, val in queries[:k]: # 前 k 个查询是否满足
diff[l] += val
diff[r + 1] -= val
# 计算前缀和
for x, sum_d in zip(nums, accumulate(diff)):
# 如果x大于当前前缀和,则不满足要求(操作次数将所有元素变为0)
if x > sum_d:
return False
return True
q = len(queries)
# 这里我们使用 左闭右开 的二分查找(即 [left, right) 区间)
# right = q + 1 表示解可能的最大范围是 [0, q](因为查询索引从 0 到 q-1)
# 如果 right = q,当 check(q) 为 True 时,right 无法再向右扩展,可能漏掉解。
# 即当left+1=q 时,right = n+1
left, right = -1, q + 1
# 二分查找
while left + 1 < right:
mid = (left + right) // 2
if check(mid):
right = mid
else:
left = mid
return right if right <= q else -1