[每日一题] 3355. 零数组变换 i
文章目录
- 1. 题目链接
- 2. 题目描述
- 3. 题目示例
- 4. 解题思路
- 5. 题解代码
- 6. 复杂度分析
1. 题目链接
3355. 零数组变换 I - 力扣(LeetCode)
2. 题目描述
给定一个长度为 n
的整数数组 nums
和一个二维数组 queries
,其中 queries[i] = [li, ri]
。
对于每个查询 queries[i]
:
- 在
nums
的下标范围[li, ri]
内选择一个下标 子集。 - 将选中的每个下标对应的元素值减 1。
零数组 是指所有元素都等于 0 的数组。
如果在按顺序处理所有查询后,可以将 nums
转换为 零数组 ,则返回 true
,否则返回 false
。
3. 题目示例
示例 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],这不是一个零数组。
4. 解题思路
- 问题理解:
- 给定一个整数数组
nums
和一个查询数组queries
,其中每个查询queries[i] = [l, r]
表示对nums
的子数组nums[l..r]
中的每个元素减一。 - 判断是否可以通过执行所有查询,将
nums
的所有元素变为 0。
- 给定一个整数数组
- 关键思路:
- 差分数组:使用差分数组高效处理区间操作(如批量减一)。
- 前缀和计算:通过差分数组的前缀和得到每个位置的实际操作次数。
- 可行性判断:检查每个元素的值是否可以被对应的操作次数减到 0。
- 算法流程:
- 初始化差分数组
diff
(长度为n + 1
)。 - 遍历每个查询
[l, r]
,更新差分数组:diff[l]++
表示从l
开始的所有元素加一(等价于后续操作中减一)。diff[r + 1]--
表示从r + 1
开始的所有元素减一(抵消区间外的影响)。
- 计算差分数组的前缀和
sumD
,得到每个位置的实际操作次数。 - 检查
nums[i]
是否 ≤sumD
(即能否通过操作减到 0)。
- 初始化差分数组
5. 题解代码
class Solution {public boolean isZeroArray(int[] nums, int[][] queries) {int n = nums.length;// 差分数组,用于记录区间操作的影响int[] diff = new int[n + 1];// 处理每个查询,更新差分数组for (int[] q : queries) {int l = q[0], r = q[1];// 区间 [l, r] 内的元素都加一diff[l]++;// 差分数组的 r+1 位置减一,用于抵消区间外的影响diff[r + 1]--;}// 计算差分数组的前缀和,得到每个位置的实际操作次数int sumD = 0;for (int i = 0; i < n; i++) {sumD += diff[i];// 如果 nums[i] 的值大于其被减去的次数,则无法变为 0if (nums[i] > sumD) {return false;}}return true;}
}
6. 复杂度分析
- 时间复杂度:
- 初始化差分数组:O(n)。
- 处理查询:O(m),其中
m
是查询数量。 - 计算前缀和和检查:O(n)。
- 总体时间复杂度:O(n + m)。
- 空间复杂度:
- 差分数组:O(n)。
- 其他变量:O(1)。
- 总体空间复杂度:O(n)。