Make Array Elements Equal to Zero
EASYDescription
You are given an integer array nums.
Start by selecting a starting position curr such that nums[curr] == 0, and choose a movement direction of either left or right.
After that, you repeat the following process:
- If
curris out of the range[0, n - 1], this process ends. - If
nums[curr] == 0, move in the current direction by incrementingcurrif you are moving right, or decrementingcurrif you are moving left. - Else if
nums[curr] > 0:- Decrement
nums[curr]by 1. - Reverse your movement direction (left becomes right and vice versa).
- Take a step in your new direction.
- Decrement
A selection of the initial position curr and movement direction is considered valid if every element in nums becomes 0 by the end of the process.
Return the number of possible valid selections.
Example 1:
Input: nums = [1,0,2,0,3]
Output: 2
Explanation:
The only possible valid selections are the following:
- Choose
curr = 3, and a movement direction to the left.[1,0,2,0,3] -> [1,0,2,0,3] -> [1,0,1,0,3] -> [1,0,1,0,3] -> [1,0,1,0,2] -> [1,0,1,0,2] -> [1,0,0,0,2] -> [1,0,0,0,2] -> [1,0,0,0,1] -> [1,0,0,0,1] -> [1,0,0,0,1] -> [1,0,0,0,1] -> [0,0,0,0,1] -> [0,0,0,0,1] -> [0,0,0,0,1] -> [0,0,0,0,1] -> [0,0,0,0,0].
- Choose
curr = 3, and a movement direction to the right.[1,0,2,0,3] -> [1,0,2,0,3] -> [1,0,2,0,2] -> [1,0,2,0,2] -> [1,0,1,0,2] -> [1,0,1,0,2] -> [1,0,1,0,1] -> [1,0,1,0,1] -> [1,0,0,0,1] -> [1,0,0,0,1] -> [1,0,0,0,0] -> [1,0,0,0,0] -> [1,0,0,0,0] -> [1,0,0,0,0] -> [0,0,0,0,0].
Example 2:
Input: nums = [2,3,4,0,4,1,0]
Output: 0
Explanation:
There are no possible valid selections.
Constraints:
1 <= nums.length <= 1000 <= nums[i] <= 100- There is at least one element
iwherenums[i] == 0.
Approaches
Checkout 2 different approaches to solve Make Array Elements Equal to Zero. Click on different approaches to view the approach and algorithm in detail.
Optimized Simulation with TreeSet
The brute-force simulation can be slow because of the time spent traversing blocks of zeros one step at a time. We can optimize this by skipping over consecutive zeros in a single operation. A TreeSet is an effective data structure for this purpose, as it can maintain the sorted indices of non-zero elements and find the next one in a given direction in logarithmic time.
Algorithm
- The overall structure is the same as the brute-force approach: iterate through all
(start_position, start_direction)pairs. - For each simulation, instead of a simple array, use a
TreeSetto store the indices of all non-zero elements. This allows for efficient queries of the next non-zero index. - Initialize the simulation with a copy of
nums, theTreeSetof non-zero indices,curr, anddir. - Loop as long as
curris within bounds: a. Ifnums_copy[curr] > 0: i. Decrementnums_copy[curr]. ii. Ifnums_copy[curr]becomes 0, removecurrfrom theTreeSet. iii. Reverse direction and move:dir *= -1,curr += dir. b. Ifnums_copy[curr] == 0: i. Instead of moving one step at a time, find the next non-zero element in the current direction using theTreeSet. ii. If moving right (dir=1), find the smallest index in theTreeSetthat is greater thancurr. This is done viatreeSet.ceiling(curr + 1). iii. If moving left (dir=-1), find the largest index in theTreeSetthat is less thancurr. This is done viatreeSet.floor(curr - 1). iv. If a next non-zero index is found, jumpcurrto that index. Otherwise, jumpcurrout of bounds. - After the loop terminates, the selection is valid if and only if the
TreeSetof non-zero indices is empty.
In this approach, we enhance the simulation by maintaining a TreeSet of indices where the array value is positive. When the simulation is at a position curr with a value of 0, instead of moving one step, we query the TreeSet to find the index of the next non-zero element in the current direction. This allows us to jump over entire blocks of zeros instantly.
For a rightward movement, treeSet.ceiling(curr + 1) gives us the next non-zero index. For a leftward movement, treeSet.floor(curr - 1) provides the previous non-zero index. If no such index exists, it means we've moved past all remaining non-zero numbers in that direction, and we can jump curr out of bounds to terminate that path segment.
When a non-zero element at an index is decremented to zero, we must remove that index from the TreeSet. This keeps our set of non-zero indices up-to-date. This optimization significantly reduces the number of steps in the simulation, especially for sparse arrays with large blocks of zeros.
class Solution {
public int makeArrayElementsEqualtoZero(int[] nums) {
int n = nums.length;
java.util.List<Integer> zeroIndices = new java.util.ArrayList<>();
for (int i = 0; i < n; i++) {
if (nums[i] == 0) {
zeroIndices.add(i);
}
}
int validCount = 0;
for (int startIdx : zeroIndices) {
if (isSelectionValid(nums.clone(), startIdx, 1)) {
validCount++;
}
if (isSelectionValid(nums.clone(), startIdx, -1)) {
validCount++;
}
}
return validCount;
}
private boolean isSelectionValid(int[] currentNums, int startCurr, int startDir) {
int n = currentNums.length;
java.util.TreeSet<Integer> nonZeroIndices = new java.util.TreeSet<>();
for (int i = 0; i < n; i++) {
if (currentNums[i] > 0) {
nonZeroIndices.add(i);
}
}
if (nonZeroIndices.isEmpty()) {
return true;
}
int curr = startCurr;
int dir = startDir;
while (curr >= 0 && curr < n) {
if (currentNums[curr] > 0) {
currentNums[curr]--;
if (currentNums[curr] == 0) {
nonZeroIndices.remove(curr);
}
dir *= -1;
curr += dir;
} else { // currentNums[curr] == 0
if (dir == 1) {
Integer nextNonZero = nonZeroIndices.ceiling(curr + 1);
curr = (nextNonZero != null) ? nextNonZero : n;
} else { // dir == -1
Integer prevNonZero = nonZeroIndices.floor(curr - 1);
curr = (prevNonZero != null) ? prevNonZero : -1;
}
}
}
return nonZeroIndices.isEmpty();
}
}
Complexity Analysis
Pros and Cons
- Significantly faster than the naive simulation, especially for sparse arrays.
- The time complexity is well within typical limits for competitive programming platforms.
- Slightly more complex to implement due to the use of a
TreeSet.
Code Solutions
Checking out 3 solutions in different languages for Make Array Elements Equal to Zero. Click on different languages to view the code.
Video Solution
Watch the video walkthrough for Make Array Elements Equal to Zero
Similar Questions
5 related questions you might find useful
Patterns:
Data Structures:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.