leetcode 3355. 零数组变换 I 中等
给定一个长度为 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 <= 10^5
0 <= nums[i] <= 10^5
1 <= queries.length <= 10^5
queries[i].length == 2
0 <= li <= ri < nums.length
分析:这道题的操作是区间修改,单点查询,可以用差分数组解决。
构建差分数组 diff 的长度为 n+1,(n 是数组 nums 长度),用于记录每个查询对操作次数的增量影响。对每个查询区间 [left,right],在 diff[left] 处 +1,表示从 left 开始操作次数增加;在 diff[right+1] 处 −1,表示 right+1 之后的操作次数恢复原状。处理完全部操作后,根据 diff 数组恢复 nums 数组,如果 nums 数组中某个数大于 0,则说明不能全部转化为零数组,否则可以。注意减为负数的情况也属于可以转化。
bool isZeroArray(int* nums, int numsSize, int** queries, int queriesSize, int* queriesColSize) {int diff[numsSize+5];diff[0]=nums[0];for(int i=1;i<numsSize;++i)diff[i]=nums[i]-nums[i-1];for(int i=0;i<queriesSize;++i)diff[queries[i][0]]--,diff[queries[i][1]+1]++;nums[0]=diff[0];if(nums[0]>0)return false;for(int i=1;i<numsSize;++i){nums[i]=nums[i-1]+diff[i];if(nums[i]>0)return false;}return true;
}