---
# System prepended metadata

title: LC 2772. Apply Operations to Make All Array Elements Equal to Zero
tags: [medium, leedcode, Difference Array, Greedy, python]

---

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

### [Problem link](https://leetcode.com/problems/apply-operations-to-make-all-array-elements-equal-to-zero/)

###### tags: `leedcode` `python` `medium` `Greedy` `Difference Array`

You are given a  **0-indexed**  integer array <code>nums</code> and a positive integer <code>k</code>.

You can apply the following operation on the array  **any**  number of times:

- Choose  **any**  subarray of size <code>k</code> from the array and  **decrease**  all its elements by <code>1</code>.

Return <code>true</code> if you can make all the array elements equal to <code>0</code>, or <code>false</code> otherwise.

A  **subarray**  is a contiguous non-empty part of an array.

**Example 1:** 

```
Input: nums = [2,2,3,1,1,0], k = 3
Output: true
Explanation: We can do the following operations:
- Choose the subarray [2,2,3]. The resulting array will be nums = [1,1,2,1,1,0].
- Choose the subarray [2,1,1]. The resulting array will be nums = [1,1,1,0,0,0].
- Choose the subarray [1,1,1]. The resulting array will be nums = [0,0,0,0,0,0].
```

**Example 2:** 

```
Input: nums = [1,3,1,1], k = 2
Output: false
Explanation: It is not possible to make all the array elements equal to 0.
```

 **Constraints:** 

- <code>1 <= k <= nums.length <= 10<sup>5</sup></code>
- <code>0 <= nums[i] <= 10<sup>6</sup></code>

## Solution 1 (TLE)
```python=
class Solution:
    def checkArray(self, nums: List[int], k: int) -> bool:
        n = len(nums)
        arr = [0] * n

        for i in range(n - k + 1):
            if arr[i] > nums[i]:
                return False
            diff = nums[i] - arr[i]
            for j in range(i, i + k):
                arr[j] += diff

        for i in range(n - k + 1, n):
            if arr[i] != nums[i]:
                return False

        return True
```

## Solution 2 - Greedy & Difference Array (從nums往下扣)
```python=
class Solution:
    def checkArray(self, nums: List[int], k: int) -> bool:
        n = len(nums)
        diff = [0] * (n + 1)

        # build difference array
        diff[0] = nums[0]
        for i in range(1, n):
            diff[i] = nums[i] - nums[i - 1]

        for i in range(n):
            delta = diff[i]
            if delta < 0:  # 如果<0代表nums[i]左側的數字太大, 沒救.
                return False
            if i + k < n + 1:
                diff[i] -= delta
                diff[i + k] += delta

        # diff[-2]才是代表nums[-1], 如果diff[-2] == 0, 則代表 
        # 有辦法讓nums的所有數字皆為0.
        return diff[-2] == 0
```

## Solution 3 - Greedy & Difference Array (從0往上加)
```python=
class Solution:
    def checkArray(self, nums: List[int], k: int) -> bool:
        n = len(nums)
        diff = [0] * (n + 1)
        
        cur = 0
        for i in range(n):
            cur += diff[i]
            if cur > nums[i]:
                return False
            delta = nums[i] - cur
            if delta > 0 and i + k < n + 1:
                diff[i] += delta
                diff[i + k] -= delta
            cur += delta

        return cur + diff[-1] == 0
```

>### Complexity
>n = nums.length
>|             | Time Complexity | Space Complexity |
>| ----------- | --------------- | ---------------- |
>| Solution 1  | O($n^2$)        | O(n)             |
>| Solution 1  | O(n)            | O(n)             |
>| Solution 1  | O(n)            | O(n)             |


## Note
[官神yt](https://youtu.be/7R7-4eIjWqM)

有點greedy的想法, 從左往右一個一個檢查, 想辦法讓當前檢查的數字為0
ex: nums = [2, 4, 3, 1], k = 2
=> nums = [0, 2, 3, 1]
=> nums = [0, 0, 1, 1]
=> nums = [0, 0, 0, 0]

但是這樣從左到右遍歷一次, 假設n = 10000, k = 100, 會做(n - k)*k次減法, 這樣會超時.

所以就出現了不用每次都要慢慢做k次減法的方法--Difference array.
[difference array介紹](https://zhuanlan.zhihu.com/p/301509170)

建議不懂difference array的話先看一下介紹, 不然會跟我一樣聽不懂官神的解說.
