Zero Array After Queries

Zero Array After Queries

You are given an integer array nums and a list of queries, where each query is a pair [li, ri] representing a range. Each query allows you to decrement any subset of elements in the range [li, ri] by 1. Your task is to determine if it is possible to make every element in nums equal to zero after applying all queries in order.

Example

Input:

nums = [1, 0, 1] queries = [[0, 2]]

Output:

true

Explanation:
We can select indices 0 and 2 and decrement both by 1 to obtain [0, 0, 0].

Best Data Structure for the Job

We are working with multiple range updates and need to evaluate coverage over indices. The best choice here is the difference array combined with a prefix sum. It allows efficient range additions and helps track how many times each index is affected by the queries.

Different Approaches

Approach 1: Brute Force

This naive method iterates over every index for every query and performs the decrement operations directly.

class Solution { public boolean canTransformToZeroArray(int[] nums, int[][] queries) { for (int[] query : queries) { int l = query[0]; int r = query[1]; for (int i = l; i <= r; i++) { if (nums[i] > 0) { nums[i]--; } } } for (int num : nums) { if (num != 0) return false; } return true; } }

Why it’s not scalable:
Time complexity becomes O(q * n) in the worst case, which is not efficient for large inputs.

Approach 2: Count Query Coverage (Intermediate)

Rather than decrementing values, this method counts how many times each index is covered by the queries. At the end, we check if each nums[i] can be reduced to zero using the number of times it was covered.

class Solution { public boolean canTransformToZeroArray(int[] nums, int[][] queries) { int n = nums.length; int[] coverage = new int[n]; for (int[] query : queries) { int l = query[0]; int r = query[1]; for (int i = l; i <= r; i++) { coverage[i]++; } } for (int i = 0; i < n; i++) { if (nums[i] > coverage[i]) return false; } return true; } }

Improvement:
We avoid modifying nums and only count coverage, but it's still O(q * range length), which may not be efficient for wide ranges.

Approach 3: Optimized Using Difference Array and Prefix Sum

This is the most efficient solution. We use a difference array to record how many times each index is affected. Instead of updating the entire range, we update the boundaries of the range and later compute the prefix sum.

class Solution { public boolean canTransformToZeroArray(int[] nums, int[][] queries) { int n = nums.length; int[] diff = new int[n + 1]; for (int[] query : queries) { int l = query[0]; int r = query[1]; diff[l]++; if (r + 1 < n) { diff[r + 1]--; } } int[] prefix = new int[n]; prefix[0] = diff[0]; for (int i = 1; i < n; i++) { prefix[i] = prefix[i - 1] + diff[i]; } for (int i = 0; i < n; i++) { if (nums[i] > prefix[i]) { return false; } } return true; } }

Why it works:
Each query is processed in constant time, and we only do a single pass for prefix sum and comparison, giving a significant performance boost.

⚠️ Common Mistakes and Pitfalls

  • Modifying the array directly for every query, leading to timeouts.

  • Off-by-one errors in the difference array update (especially at r + 1).

  • Forgetting to compute the prefix sum before checking the results.

  • Not handling edge cases like queries beyond the array bounds properly.

📊 Time and Space Complexity Analysis

Approach      Time Complexity       Space Complexity
Brute Force        O(n * q)        O(1)
Count Coverage per Index        O(n * avg_range)        O(n)
Optimized (Diff + Prefix Sum)        O(n + q)        O(n)

  • n is the length of the input array nums

  • q is the number of queries

🌍 Real-World Applications

  • Inventory systems: Tracking the effect of overlapping orders or shipments.

  • Game development: Applying overlapping buffs or effects over different zones.

  • Resource planning: Determining whether supply meets demand across overlapping requests.

  • Scheduling and calendar systems: Evaluating coverage or conflicts in timeslot ranges.

 

I hope you found this article insightful! Keep exploring, keep learning, and don’t forget to check back daily for more exciting problem breakdowns. If you know someone who would benefit from this, share it with them and help them grow too! That’s it for today—see you in the next post!

                                                                                                                                         Signing off!! 

                                                                                                Master DSA One Problem at a Time :)

Comments

Popular posts from this blog

Divisible Drama — Who’s In, Who’s Out?

Trailing Zeros in Factorial – How Many and Why?

Minimum equal sum