3355. 零数组变换 I
来源第 424 场周赛 Q2难度中等分数1591
题目描述
给定一个长度为 n 的整数数组 nums 和一个二维数组 queries,其中 queries[i] = [li, ri]。
对于每个查询 queries[i]:
- 在
nums的下标范围[li, ri]内选择一个下标 子集。 - 将选中的每个下标对应的元素值减 1。
零数组 是指所有元素都等于 0 的数组。
如果在按顺序处理所有查询后,可以将 nums 转换为 零数组 ,则返回 true,否则返回 false。
示例 1:
输入: nums = [1,0,1], queries = [[0,2]]
输出: true
解释:
- 对于 i = 0:
- 选择下标子集
[0, 2]并将这些下标处的值减 1。 - 数组将变为
[0, 0, 0],这是一个零数组。
- 选择下标子集
示例 2:
输入: nums = [4,3,2,1], queries = [[1,3],[0,2]]
输出: false
解释:
- 对于 i = 0:
- 选择下标子集
[1, 2, 3]并将这些下标处的值减 1。 - 数组将变为
[4, 2, 1, 0]。
- 选择下标子集
- 对于 i = 1:
- 选择下标子集
[0, 1, 2]并将这些下标处的值减 1。 - 数组将变为
[3, 1, 0, 0],这不是一个零数组。
- 选择下标子集
提示:
1 <= nums.length <= 1050 <= nums[i] <= 1051 <= queries.length <= 105queries[i].length == 20 <= li <= ri < nums.length
解法
方法一:差分数组
思考
每个询问把 \([l,r]\) 各减一(实际是提供一次覆盖),问全部询问用完后能否把 \(\textit{nums}\) 盖到 \(0\)。\(n,m \le 10^5\),不能逐询问改数组。
覆盖次数是区间加,差分数组在 \(l\) 加一、\(r+1\) 减一,前缀和即每位被覆盖次数。
若某位 \(\textit{nums}[i]\) 大于覆盖次数,则无法归零。
我们可以使用差分数组来解决这个问题。
定义一个长度为 \(n + 1\) 的数组 \(d\),初始值全部为 \(0\)。对于每个查询 \([l, r]\),我们将 \(d[l]\) 加 \(1\),将 \(d[r + 1]\) 减 \(1\)。
然后我们遍历数组 \(d\) 在 \([0, n - 1]\) 范围内的每个元素,累加前缀和 \(s\),如果 \(\textit{nums}[i] > s\),说明 \(\textit{nums}\) 不能转换为零数组,返回 \(\textit{false}\)。
遍历结束后,返回 \(\textit{true}\)。
时间复杂度 \(O(n + m)\),空间复杂度 \(O(n)\)。其中 \(n\) 和 \(m\) 分别为数组 \(\textit{nums}\) 和 \(\textit{queries}\) 的长度。
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |