Facebook Pixel

3354. Make Array Elements Equal to Zero


Problem Description

You are given an integer array nums. The task is to start by selecting a starting position curr such that nums[curr] == 0, and then choose a movement direction, either left or right. Following that, repeat the following process:

  • If curr is out of the range [0, n - 1], the process ends.
  • If nums[curr] == 0, move in the current direction by incrementing curr if moving right, or decrementing curr if moving left.
  • If nums[curr] > 0:
    • Decrease nums[curr] by 1.
    • Reverse your movement direction (left becomes right and vice versa).
    • Take a step in your new direction.

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. The goal is to return the number of possible valid selections.

Intuition

The problem involves navigating through an array with certain initial choices, and the goal is to identify configurations that will result in the array becoming all zeros. The key insight is to think in terms of balance. We can align this "balance" concept by looking at prefix sums:

  1. Calculate a total sum s of the array.
  2. For each zero-value element in the array, calculate the sum of all the elements to its left (l). The elements to the right will sum to s - l.
  3. Check two scenarios:
    • If the sum of the left and right are equal (l = s - l), moving from the zero in either direction will eventually balance the whole array to zero. Such a case can be approached from both directions, hence contributes 2 valid solutions.
    • If the absolute difference between the two sums (|l - (s - l)|) is 1, start from the zero and choose the direction towards the larger side to balance the entire array to zeros. This scenario provides 1 valid solution.

This logic is implemented efficiently with a single pass through the array and uses the prefix calculation.

Learn more about Prefix Sum patterns.

Solution Approach

The solution leverages the concept of prefix sums to keep track of the potential valid starting points and directions. Here's how it works:

  1. Summation: First, compute the total sum s of all elements in the array nums.

  2. Initialization: Initialize two variables: ans (to store the number of valid selections) and l (to keep a running prefix sum of elements encountered thus far).

  3. Iteration: Iterate through each element x in nums:

    • If x is not zero, accumulate it into l.
    • If x is zero:
      • Check if 2 * l == s. This condition implies the sum of elements on both sides of the current zero are equal, hence the array can be balanced by starting movement either left or right from this point. Increase ans by 2 for these two possible directions.
      • Otherwise, if |2 * l - s| == 1, it indicates that the absolute difference between the left and right sums is 1. Depending on which side is larger, the direction from this zero value can be selected. Increase ans by 1, as there's only one valid direction.
  4. Return Result: Finally, return ans as the count of valid selections.

Using this approach, the problem is solved efficiently with a single pass through the array, making it a linear time complexity solution.

Ready to land your dream job?

Unlock your dream job with a 2-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's consider the array nums = [1, 0, 2, 1, 0, 2, 3, 0] to illustrate the solution approach.

Step 1: Summation

Compute the total sum s of the array:
[ s = 1 + 0 + 2 + 1 + 0 + 2 + 3 + 0 = 9 ]

Step 2: Initialization

Initialize ans = 0 to store the number of valid selections, and l = 0 for the running prefix sum.

Step 3: Iteration

Iterate through each element:

  1. Index 0 (x = 1):
    Add x to l:
    [ l = l + 1 = 1 ]

  2. Index 1 (x = 0):
    Check conditions:

    • ( 2 \times l = 2 \times 1 = 2 \neq 9 )
    • (|2 \times l - s| = |2 - 9| = 7 \neq 1)
      No valid starting positions from this zero.
  3. Index 2 (x = 2):
    Add x to l:
    [ l = l + 2 = 3 ]

  4. Index 3 (x = 1):
    Add x to l:
    [ l = l + 1 = 4 ]

  5. Index 4 (x = 0):
    Check conditions:

    • ( 2 \times l = 2 \times 4 = 8 \neq 9 )
    • (|2 \times l - s| = |8 - 9| = 1)
      The absolute difference is 1, thus a selection starting from here can balance the array.
      Increment ans by 1:
      [ ans = 1 ]
  6. Index 5 (x = 2):
    Add x to l:
    [ l = l + 2 = 6 ]

  7. Index 6 (x = 3):
    Add x to l:
    [ l = l + 3 = 9 ]

  8. Index 7 (x = 0):
    Check conditions:

    • ( 2 \times l = 2 \times 9 = 18 \neq 9 )
    • (|2 \times l - s| = |18 - 9| = 9 \neq 1)
      No valid selections from this zero.

Step 4: Return Result

The count of valid selections is ( \text{ans} = 1 ).

Thus, using the solution approach, we find that there is 1 valid way to select a starting position and direction so that all elements in nums would eventually become zero.

Solution Implementation

1from typing import List
2
3class Solution:
4    def countValidSelections(self, nums: List[int]) -> int:
5        # Calculate the total sum of the list
6        total_sum = sum(nums)
7        # Initialize answer and cumulative left sum to zero
8        ans = left_sum = 0
9
10        # Iterate through each element in the list
11        for num in nums:
12            if num != 0:
13                # Add to left_sum if the element is non-zero
14                left_sum += num
15            else:
16                # Check if double the left_sum is equal to total_sum
17                if left_sum * 2 == total_sum:
18                    ans += 2
19                # Check if the absolute difference between double the left_sum and total_sum is 1
20                elif abs(left_sum * 2 - total_sum) == 1:
21                    ans += 1
22        return ans
23
1import java.util.Arrays;
2
3class Solution {
4
5    // Method to count valid selections in the array
6    public int countValidSelections(int[] nums) {
7        // Calculate the sum of all elements in the array
8        int totalSum = Arrays.stream(nums).sum();
9
10        int validSelectionsCount = 0;
11        int currentSum = 0;
12
13        // Iterate through each element in the array
14        for (int num : nums) {
15            // If the element is non-zero, add it to the current sum
16            if (num != 0) {
17                currentSum += num;
18            } else {
19                // Check if the current sum is half of the total sum
20                // If true, increment the count by 2
21                if (currentSum * 2 == totalSum) {
22                    validSelectionsCount += 2;
23                } 
24                // Check if the absolute difference between 
25                // double the current sum and the total sum is 1
26                // If true, increment the count by 1
27                else if (Math.abs(currentSum * 2 - totalSum) <= 1) {
28                    validSelectionsCount++;
29                }
30            }
31        }
32
33        return validSelectionsCount;
34    }
35}
36
1#include <vector>
2#include <numeric> // For std::accumulate
3#include <cmath>   // For std::abs
4
5class Solution {
6public:
7    int countValidSelections(std::vector<int>& nums) {
8        // Calculate the sum of all elements in nums
9        int total_sum = std::accumulate(nums.begin(), nums.end(), 0);
10      
11        int valid_selections = 0; // Initialize the counter for valid selections
12        int partial_sum = 0;      // Initialize partial sum for the subarray
13      
14        // Iterate through each element in the nums vector
15        for (int x : nums) {
16            if (x != 0) {
17                // If the current element is non-zero, add it to the partial sum
18                partial_sum += x;
19            } else {
20                // If the current element is zero, check the conditions
21                if (partial_sum * 2 == total_sum) {
22                    // If twice the partial sum equals the total sum, add 2 to valid selections
23                    valid_selections += 2;
24                } else if (std::abs(partial_sum * 2 - total_sum) <= 1) {
25                    // If the absolute difference between twice the partial sum and the total sum is at most 1, add 1 to valid selections
26                    ++valid_selections;
27                }
28            }
29        }
30      
31        return valid_selections; // Return the count of valid selections
32    }
33};
34
1function countValidSelections(nums: number[]): number {
2    // Calculate the sum of all elements in the array `nums`
3    const totalSum = nums.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
4  
5    // Initialize answer and left sum as zero
6    let answer = 0;
7    let leftSum = 0;
8  
9    // Iterate through each number in the array
10    for (const num of nums) {
11        if (num) {
12            // Increment the left sum when the current number is non-zero
13            leftSum += num;
14        } else {
15            // Check if the current left sum multiplied by 2 equals the total sum
16            if (leftSum * 2 === totalSum) {
17                // Increment answer by 2 if condition is met
18                answer += 2;
19            } else if (Math.abs(leftSum * 2 - totalSum) <= 1) {
20                // Increment answer by 1 if the difference is at most 1
21                ++answer;
22            }
23        }
24    }
25  
26    // Return the final computed answer
27    return answer;
28}
29

Time and Space Complexity

The time complexity of the code is O(n), where n is the length of the array nums. This is because each element in the array is processed exactly once in a single pass through the array.

The space complexity of the code is O(1), as no additional data structures that grow with the input size n are used. The variables s, ans, and l consume constant space.

Learn more about how to find time and space complexity quickly.


Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:
Question 1 out of 10

Which algorithm is best for finding the shortest distance between two points in an unweighted graph?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!


Load More