# 13.03.2025 [3356. Zero Array Transformation II]
Min queries (l..r, v) to decrease nums by v to 0 #medium #line_sweep
13.03.2025
3356. Zero Array Transformation II medium blog post substack youtube
Join me on Telegram
Problem TLDR
Min queries (l..r, v) to decrease nums by v to 0 #medium #line_sweep
Intuition
Didn't solve without the hint: the binary search works here.
Let's try example:
// 0 1 2 3 0 1 2 3
// 2 5 2 3 j 0..2 2, 1..3 1, 2..3 2, 1..1 3
// [...] 2 0
// [...] 1 1
// [] 3 3
// [.] 2 2
I've tried to do a single pass solution:
sort the queries by left border
on each number take all left borders and remove all right borders (I used PriorityQueue for removals)
try to pick max k (that's where I failed, there is no way to do this on a sorted queries right)
So, just sorting didn't work. I have to resort to the hint and consider the BinarySearch.
Let's simplify the picking of
k
:
we already know the
k
(middle of the BinarySearch range)drop all queries that bigger
calculate the sum
That's worked out. However, solution no longer require the sorting, just prepare line sweep array: add v at the range start l, remove v at the range end r + 1. Much faster.
And now, the other's guy solution: didn't have to do the Binary Search at all, just do the same line sweep, and dynamically adjust current sum when increasing the k.
Approach
try to solve at least in 40 minutes mark
then look for the hints
after 1 hour it's a fair game to steal the solution
Complexity
Time complexity: $$O(n)$$
Space complexity: $$O(n)$$
Code
fun minZeroArray(nums: IntArray, q: Array<IntArray>): Int {
var k = 0; var sum = 0; val s = IntArray(nums.size + 1)
for (i in nums.indices) {
sum += s[i]
while (sum < nums[i]) {
if (k >= q.size) return -1
val (l, r, v) = q[k++]
s[l] += v; s[r + 1] -= v
if (i in l..r) sum += v
}
}
return k
}
pub fn min_zero_array(nums: Vec<i32>, q: Vec<Vec<i32>>) -> i32 {
let (mut k, mut sum, mut s) = (0, 0, vec![0; nums.len() + 1]);
for i in 0..nums.len() {
sum += s[i];
while sum < nums[i] {
if k >= q.len() { return -1 }
let (l, r, v) = (q[k][0] as usize, q[k][1] as usize, q[k][2]);
s[l] += v; s[r + 1] -= v; k += 1;
if (l..=r).contains(&i) { sum += v }
}
}; k as _
}
int minZeroArray(vector<int>& nums, vector<vector<int>>& q) {
vector<int> s(size(nums) + 1); int k = 0, sum = 0;
for (int i = 0; i < size(nums); ++i) {
sum += s[i];
while (sum < nums[i]) {
if (k >= size(q)) return -1;
int l = q[k][0], r = q[k][1], v = q[k++][2];
s[l] += v; s[r + 1] -= v;
if (l <= i && i <= r) sum += v;
}
} return k;
}