LeetCode 题解工作台
零数组变换 II
给你一个长度为 n 的整数数组 nums 和一个二维数组 queries ,其中 queries[i] = [l i , r i , val i ] 。 每个 queries[i] 表示在 nums 上执行以下操作: 将 nums 中 [l i , r i ] 范围内的每个下标对应元素的值 最多 减…
3
题型
6
代码语言
3
相关题
当前训练重点
中等 · 二分·搜索·答案·空间
答案摘要
我们注意到,查询的个数越多,越容易使得数组变成零数组,这存在单调性。因此,我们可以二分枚举查询的个数,判断在前 k 个查询下,是否可以将数组变成零数组。 我们定义二分查找的左边界 和右边界 ,初始时 $l = 0$, $r = m + 1$,其中 是查询的个数。我们定义一个函数 ,表示在前 个查询下,是否可以将数组变成零数组。我们可以使用差分数组来维护每个元素的值。
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路
题目描述
给你一个长度为 n 的整数数组 nums 和一个二维数组 queries,其中 queries[i] = [li, ri, vali]。
每个 queries[i] 表示在 nums 上执行以下操作:
- 将
nums中[li, ri]范围内的每个下标对应元素的值 最多 减少vali。 - 每个下标的减少的数值可以独立选择。
零数组 是指所有元素都等于 0 的数组。
返回 k 可以取到的 最小非负 值,使得在 顺序 处理前 k 个查询后,nums 变成 零数组。如果不存在这样的 k,则返回 -1。
示例 1:
输入: nums = [2,0,2], queries = [[0,2,1],[0,2,1],[1,1,3]]
输出: 2
解释:
- 对于 i = 0(l = 0, r = 2, val = 1):
- 在下标
[0, 1, 2]处分别减少[1, 0, 1]。 - 数组将变为
[1, 0, 1]。
- 在下标
- 对于 i = 1(l = 0, r = 2, val = 1):
- 在下标
[0, 1, 2]处分别减少[1, 0, 1]。 - 数组将变为
[0, 0, 0],这是一个零数组。因此,k的最小值为 2。
- 在下标
示例 2:
输入: nums = [4,3,2,1], queries = [[1,3,2],[0,2,1]]
输出: -1
解释:
- 对于 i = 0(l = 1, r = 3, val = 2):
- 在下标
[1, 2, 3]处分别减少[2, 2, 1]。 - 数组将变为
[4, 1, 0, 0]。
- 在下标
- 对于 i = 1(l = 0, r = 2, val = 1):
- 在下标
[0, 1, 2]处分别减少[1, 1, 0]。 - 数组将变为
[3, 0, 0, 0],这不是一个零数组。
- 在下标
提示:
1 <= nums.length <= 1050 <= nums[i] <= 5 * 1051 <= queries.length <= 105queries[i].length == 30 <= li <= ri < nums.length1 <= vali <= 5
解题思路
方法一:差分数组 + 二分查找
我们注意到,查询的个数越多,越容易使得数组变成零数组,这存在单调性。因此,我们可以二分枚举查询的个数,判断在前 k 个查询下,是否可以将数组变成零数组。
我们定义二分查找的左边界 和右边界 ,初始时 , ,其中 是查询的个数。我们定义一个函数 ,表示在前 个查询下,是否可以将数组变成零数组。我们可以使用差分数组来维护每个元素的值。
定义一个长度为 的数组 ,初始值全部为 。对于前 个查询的每个查询 ,我们将 加 ,将 减 。
然后我们遍历数组 在 范围内的每个元素,累加前缀和 ,如果 ,说明 不能转换为零数组,返回 。
我们在二分查找的过程中,如果 返回 ,说明可以将数组变成零数组,我们就将右边界 更新为 ,否则将左边界 更新为 。
最后,我们判断 是否大于 ,如果是,则返回 -1,否则返回 。
时间复杂度 ,空间复杂度 。其中 和 分别为数组 和 的长度。
class Solution:
def minZeroArray(self, nums: List[int], queries: List[List[int]]) -> int:
def check(k: int) -> bool:
d = [0] * (len(nums) + 1)
for l, r, val in queries[:k]:
d[l] += val
d[r + 1] -= val
s = 0
for x, y in zip(nums, d):
s += y
if x > s:
return False
return True
m = len(queries)
l = bisect_left(range(m + 1), True, key=check)
return -1 if l > m else l
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | complexity is O(N + M) because each prefix sum simulation runs in O(N) and binary search iterates log(M) times, but combined efficiently with cumulative sums. Space complexity is O(N) for the prefix sum array to track cumulative additions. |
| 空间 | O(N) |
面试官常问的追问
外企场景- question_mark
Consider if binary search can reduce the number of simulations instead of checking each query sequence.
- question_mark
Using prefix sums indicates you understand efficient range update techniques in arrays.
- question_mark
Identifying a Zero Array requirement shows awareness of validation failure modes and cumulative effects.
常见陷阱
外企场景- error
Simulating each query individually without prefix sums can lead to TLE for large N and M.
- error
Forgetting to handle queries that extend beyond the array bounds can cause index errors.
- error
Misinterpreting the requirement to return -1 when no sequence can zero the array leads to incorrect outputs.
进阶变体
外企场景- arrow_right_alt
Zero Array Transformation I with fixed-length queries for simplified index management.
- arrow_right_alt
Negative Adjustment Queries where queries can subtract instead of add, changing prefix sum signs.
- arrow_right_alt
Zero Array Transformation III where queries can overlap and must be applied in a constrained order.