Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leetcode 2772. Apply Operations to Make All Array Elements Equal to Zero

Woodyiiiiiii opened this issue · comments

2772. Apply Operations to Make All Array Elements Equal to Zero

2772. Apply Operations to Make All Array Elements Equal to Zero

类似题目:
2528. Maximize the Minimum Powered City

参考资料:
[Java/C++/Python] Greedy + Sliding Window
差分数组(Python/Java/C++/Go/JS)

这道题类型是在数组内固定范围对区间元素同时加减值的操作——差分数组

一开始不知道怎么做,先从例子出发。第一个数,如果要使其变为0,那么就会使[0~k-1]范围内变为0;接着对于第二个数也是如此,所以对于每个数,他们都在范围的左端点。同时可以注意到有个累加的过程,对于一个数, 它会受到其左边范围k的所有需要减去操作的累加,这个累加值可以用一个变量来表示。

对这个变量,命名为cur,其表示的是[i-k+1~i]之间的操作值。为了保持这个值,移动时需要减去[i-k]下标的需要操作值,这个操作值可以在原数组中修改实现。最后判断该变量是否为0,表示是不是数组内所有值都是0了。

这样就类似一个滑动窗口模拟,代码如下:

class Solution {
    public boolean checkArray(int[] nums, int k) {
        int n = nums.length;
        int cur = 0;
        for (int i = 0; i < n; i++) {
            if (nums[i] < cur) {
                return false;
            }
            nums[i] -= cur;
            cur += nums[i];
            if (i - k + 1 >= 0) {
                cur -= nums[i - k + 1];
            }
        }
        return cur == 0;
    }
}

当然比较原始的写法是用一个差分数组,用来表示i位置下需要减去的操作值,也就是预先做好操作了。d[i]表示i - k位置下的操作值。

这种做法用多了一个空间,不修改原数组,在类似题目上处理的更好。

class Solution {
    public boolean checkArray(int[] nums, int k) {
        int n = nums.length;
        int cur = 0;
        int[] d = new int[n];
        for (int i = 0; i < n; i++) {
            cur -= d[i];
            int x = nums[i] - cur;
            if (x < 0) {
                return false;
            } else if (x == 0) {
                continue;
            } else {
                if (i + k - 1 >= n) {
                    return false;
                }
                cur += x;
                if (i + k < n) {
                    d[i + k] = x;
                } 
            }
        }
        return true;
    }
}