[每日一题] 3355. 零数组变换 i

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. 解题思路


  1. 问题理解
    • 给定一个整数数组 nums 和一个查询数组 queries,其中每个查询 queries[i] = [l, r] 表示对 nums 的子数组 nums[l..r] 中的每个元素减一。
    • 判断是否可以通过执行所有查询,将 nums 的所有元素变为 0。
  2. 关键思路
    • 差分数组:使用差分数组高效处理区间操作(如批量减一)。
    • 前缀和计算:通过差分数组的前缀和得到每个位置的实际操作次数。
    • 可行性判断:检查每个元素的值是否可以被对应的操作次数减到 0。
  3. 算法流程
    • 初始化差分数组 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] 的值大于其被减去的次数,则无法变为 0
            if (nums[i] > sumD) {
                return false;
            }
        }
        return true;
    }
}


6. 复杂度分析


  1. 时间复杂度
    • 初始化差分数组:O(n)。
    • 处理查询:O(m),其中 m 是查询数量。
    • 计算前缀和和检查:O(n)。
    • 总体时间复杂度:O(n + m)。
  2. 空间复杂度
    • 差分数组:O(n)。
    • 其他变量:O(1)。
    • 总体空间复杂度:O(n)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值