You are given an integer array nums of length n and a 2D array queries where queries[i] = [li, ri, vali].
Each queries[i] represents the following action on nums:
Decrement the value at each index in the range [li, ri] in nums by at mostvali.
The amount by which each value is decremented can be chosen independently for each index.
A Zero Array is an array with all its elements equal to 0.
Return the minimum possible non-negative value of k, such that after processing the first k queries in sequence, nums becomes a Zero Array. If no such k exists, return -1.
Input: nums =[2,0,2], queries =[[0,2,1],[0,2,1],[1,1,3]]Output: 2Explanation:
***For i =0(l =0, r =2, val =1):*** Decrement values at indices `[0, 1, 2]` by `[1, 0, 1]` respectively.* The array will become `[1, 0, 1]`.***For i =1(l =0, r =2, val =1):*** Decrement values at indices `[0, 1, 2]` by `[1, 0, 1]` respectively.* The array will become `[0, 0, 0]`, which is a Zero Array. Therefore, the minimum value of `k`is2.
Example 2:
1
2
3
4
5
6
7
8
9
10
11
12
13
Input: nums =[4,3,2,1], queries =[[1,3,2],[0,2,1]]Output: -1Explanation:
***For i =0(l =1, r =3, val =2):*** Decrement values at indices `[1, 2, 3]` by `[2, 2, 1]` respectively.* The array will become `[4, 1, 0, 0]`.***For i =1(l =0, r =2, val =1):*** Decrement values at indices `[0, 1, 2]` by `[1, 1, 0]` respectively.* The array will become `[3, 0, 0, 0]`, which is not a Zero Array.
Method 1 - Binary Search with Range Updates Using Difference Array#
The problem requires determining the minimum number of queries needed to transform the array nums into a Zero Array (all elements 0). Each query allows decrementing values in a range [li, ri] by at most vali. A direct approach of applying queries sequentially for every possible number k is inefficient, so we use binary search to efficiently determine the smallest k that works. To quickly process the range updates for each query, a difference array is used to simulate the effects.
classSolution {
publicintminZeroArray(int[] nums, int[][] queries) {
// Binary search for the minimum number of queries neededint left = 0, right = queries.length, ans =-1;
while (left <= right) {
int mid = left + (right - left) / 2;
// Use a copy of nums to avoid modifying the original arrayint[] numsCopy = nums.clone();
if (canZero(numsCopy, queries, mid)) {
ans = mid; // If possible with 'mid' queries, record and try for fewer queries right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
// Helper function to check if nums can be reduced to a Zero Array with the first 'k' queriesprivatebooleancanZero(int[] nums, int[][] queries, int k) {
int n = nums.length;
int[] diff =newint[n + 1]; // Difference array for efficient range updates// Apply the first 'k' queriesfor (int i = 0; i < k; i++) {
int li = queries[i][0];
int ri = queries[i][1];
int vali = queries[i][2];
diff[li]-= vali; // Start decrement at index 'li'if (ri + 1 < n) {
diff[ri + 1]+= vali; // Stop decrement after index 'ri' }
}
// Simulate the effect of the difference array on numsint runningSum = 0;
for (int i = 0; i < n; i++) {
runningSum += diff[i];
nums[i]+= runningSum;
if (nums[i]> 0) {
returnfalse; // If any value remains positive, nums cannot be a Zero Array }
}
returntrue; // All elements are ≤ 0, meaning nums is a Zero Array }
}
classSolution:
defminZeroArray(self, nums: List[int], queries: List[List[int]]) -> int:
defcan_zero(nums: List[int], k: int) -> bool:
n = len(nums)
diff = [0] * (n +1) # Difference array for efficient range updates# Apply the first 'k' queriesfor i in range(k):
li, ri, val = queries[i]
diff[li] -= val # Start decrement at index 'li'if ri +1< n:
diff[ri +1] += val # Stop decrement after index 'ri'# Simulate the effect on nums running_sum =0for i in range(n):
running_sum += diff[i]
nums[i] += running_sum
if nums[i] >0:
returnFalse# nums cannot be zeroed if any value is positivereturnTrue# All elements are ≤ 0, nums is a Zero Array# Binary search for the minimum 'k' left, right =0, len(queries)
ans =-1while left <= right:
mid = (left + right) //2# Use a copy of nums to avoid modifying the original nums_copy = nums[:]
if can_zero(nums_copy, mid):
ans = mid # If it's possible with 'mid' queries right = mid -1else:
left = mid +1return ans