# 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的話先看一下介紹, 不然會跟我一樣聽不懂官神的解說.