Skip to main content

Two Pointer

Apply Operations to an Array Solution In C++/Java/Python/JS

Problem Description

You are given a 0-indexed array nums of size n that contains non-negative integers. The goal is to apply a sequence of operations to this array and return the final result after all transformations are complete.

For each index i from 0 to n - 2, you need to apply the following rule:

  • If nums[i] == nums[i + 1], then:
    • Multiply nums[i] by 2
    • Set nums[i + 1] to 0

These operations must be applied sequentially from left to right — not in parallel.

Once all operations are done, you must shift all zeros to the end of the array. The relative order of the non-zero elements should be preserved during this shift.

For example, if the array after operations is [1, 0, 2, 0, 0, 1], then after shifting the zeros to the end, the final result should be [1, 2, 1, 0, 0, 0].

The task is to return the resulting array after performing all the operations and shifting the zeros accordingly.

Example

Input:
nums = [1, 2, 2, 1, 1, 0]
Output:
[1, 4, 2, 0, 0, 0]

Explanation:
We go step-by-step through the array:

  • At index 0: 1 != 2 → skip
  • At index 1: 2 == 2 → double nums[1] to 4, set nums[2] to 0 → [1, 4, 0, 1, 1, 0]
  • At index 2: 0 != 1 → skip
  • At index 3: 1 == 1 → double nums[3] to 2, set nums[4] to 0 → [1, 4, 0, 2, 0, 0]
  • At index 4: 0 == 0 → skip (not equal in value logic)

Now shift all zeros to the end → Final result: [1, 4, 2, 0, 0, 0]

Example 2

Input:
nums = [0, 1]
Output:
[1, 0]

Explanation:
No two adjacent elements are equal, so no operation is performed. We simply shift the zero to the end → Final result: [1, 0]

Constraints

  • 2 <= nums.length <= 2000
  • 0 <= nums[i] <= 1000

At first glance, the problem seems straightforward: go through the array, apply a rule when two adjacent numbers are equal, and then clean up the zeros. The catch is to make sure the operations are done sequentially and not all at once. Also, after the operation phase, we need to handle the rearrangement (shifting zeros) without disturbing the order of the other numbers.

Brute Force Solution


Intuition

The idea is simple: scan the array once to apply the given operation — if two adjacent numbers are equal, double the first and zero out the second. Since the operations are sequential, we process the array from left to right. After that, we perform a second pass to move all zeros to the end while keeping the order of the non-zero numbers the same.

Approach

  1. Iterate through the array from index 0 to n - 2.
  2. If nums[i] == nums[i + 1], then:
    • Multiply nums[i] by 2
    • Set nums[i + 1] to 0
  3. After this pass, create a new array or modify the existing one to shift all 0s to the end.
  4. Return the resulting array.

This brute-force method runs in O(n) time overall, but we're doing two passes — one for operation and one for shifting.

Dry Run

Input:
nums = [1, 2, 2, 1, 1, 0]

Step 1: Apply Operations (Left to Right)

Initial: [1, 2, 2, 1, 1, 0]

  • i = 0: 1 != 2 → skip
  • i = 1: 2 == 2 → double nums[1] to 4, set nums[2] = 0
    → [1, 4, 0, 1, 1, 0]
  • i = 2: 0 != 1 → skip
  • i = 3: 1 == 1 → double nums[3] to 2, set nums[4] = 0
    → [1, 4, 0, 2, 0, 0]
  • i = 4: 0 != 0 → skip (not logically valid to combine two zeros)

After all operations:
[1, 4, 0, 2, 0, 0]

Step 2: Shift All Zeros to End

Scan and collect non-zero values: [1, 4, 2]
Count of zeros = 3
Final result after shifting zeros: [1, 4, 2, 0, 0, 0]

Output:
[1, 4, 2, 0, 0, 0]

Code for All Languages
C++
vector applyOperations(vector& nums) {
int n = nums.size();

// Step 1: Apply operations from left to right
for (int i = 0; i < n - 1; i++) {
    // If current and next elements are equal
    if (nums[i] == nums[i + 1]) {
        nums[i] *= 2;        // Double the current element
        nums[i + 1] = 0;     // Set the next element to 0
    }
}

// Step 2: Shift all non-zero elements to the front
vector<int> result;
for (int i = 0; i < n; i++) {
    if (nums[i] != 0) {
        result.push_back(nums[i]);
    }
}

// Step 3: Fill the rest of the array with zeros
while (result.size() < n) {
    result.push_back(0);
}

return result;
}

Java
public class ApplyOperations {
    public static int[] applyOperations(int[] nums) {
        int n = nums.length;

        // Step 1: Apply operations from left to right
        for (int i = 0; i < n - 1; i++) {
            // If two adjacent elements are equal, double the first and zero the next
            if (nums[i] == nums[i + 1]) {
                nums[i] *= 2;
                nums[i + 1] = 0;
            }
        }

        // Step 2: Create a new array and shift all non-zero elements to the front
        int[] result = new int[n];
        int idx = 0;

        for (int num : nums) {
            if (num != 0) {
                result[idx++] = num;
            }
        }

        // Remaining positions are already initialized to 0 in Java arrays
        return result;
    }
}

Python
def applyOperations(nums):
    n = len(nums)

    # Step 1: Apply operations from left to right
    for i in range(n - 1):
        if nums[i] == nums[i + 1]:
            nums[i] *= 2
            nums[i + 1] = 0

    # Step 2: Shift all non-zero elements to the front
    result = [num for num in nums if num != 0]

    # Step 3: Fill the remaining places with 0
    result += [0] * (n - len(result))

    return result

Javascript
function solve(stdin) {
    // Convert input string to array of numbers
    const nums = stdin.trim().split(/\s+/).map(Number);
    const n = nums.length;

    // Step 1: Apply operations
    for (let i = 0; i < n - 1; i++) {
        if (nums[i] === nums[i + 1]) {
            nums[i] *= 2;
            nums[i + 1] = 0;
        }
    }

    // Step 2: Move non-zero elements to front
    const result = nums.filter(num => num !== 0);

    // Step 3: Fill remaining with zeros
    while (result.length < n) {
        result.push(0);
    }

    // Print the result
    console.log(result.join(" "));
}

Time Complexity-O(n)

  • First loop (Operation Phase):
    We iterate through the array once from index 0 to `n - 2 → O(n)
  • Second loop (Filtering Non-Zero Elements):
    We go through the array again to collect all non-zero elements → O(n)
  • Third step (Filling zeros):
    We may push up to n zeros → O(n) in worst case (all zeros)

Total Time Complexity = O(n) + O(n) + O(n) = O(n)
So, the overall time complexity is O(n).

Space Complexity- O(n)

In our solution, we’re creating a new array called result to store the final answer — this includes:

  • All non-zero elements from the transformed nums array
  • Followed by enough zeros to make the result's length equal to the original array

This means:

  • In the worst case, where all elements are non-zero initially and none of them are combined or converted to zero during operation,
  • The result array will store n elements, which is a full copy of the original array.

Even though we don’t use any nested structures or additional data structures like hash maps, we are still allocating additional linear space.

So the space complexity becomes O(n) — because of the result array that holds up to n elements.

Optimized Approach

Intuition

Instead of creating a new array to store the final result, we can do everything in-place. First, apply the operations as usual. Then, instead of building a new array to shift non-zero elements, we move them forward in the same array using a two-pointer technique. This saves us from using extra space and makes the approach both time and space efficient.

Approach

  • Step 1: Apply the operations (same as before):For each index i from 0 to n - 2, if nums[i] == nums[i + 1], double nums[i] and set nums[i + 1] to 0.
  • Step 2: Shift non-zero elements in-place using a write pointer:Initialize write = 0Iterate over the array:If nums[i] != 0, set nums[write] = nums[i] and increment writeAfter loop, fill remaining elements from write to n-1 with 0

Dry Run

Input: [1, 2, 2, 1, 1, 0]

  1. After Operation Phase:
    • i = 1: 2 == 2 → nums[1] = 4, nums[2] = 0 → [1, 4, 0, 1, 1, 0]
    • i = 3: 1 == 1 → nums[3] = 2, nums[4] = 0 → [1, 4, 0, 2, 0, 0]
  2. Shifting Non-Zeros In-Place:Final array becomes: [1, 4, 2, 0, 0, 0]
    • write = 0 → place 1
    • write = 1 → place 4
    • write = 2 → skip 0
    • write = 2 → place 2

Final array becomes: [1, 4, 2, 0, 0, 0]

Code for All Languages
C++
void applyOperations(vector<int>& nums) {
    int n = nums.size();

    // Step 1: Apply operations
    for (int i = 0; i < n - 1; i++) {
        if (nums[i] == nums[i + 1]) {
            nums[i] *= 2;
            nums[i + 1] = 0;
        }
    }

    // Step 2: Shift non-zeros in-place
    int write = 0;
    for (int i = 0; i < n; i++) {
        if (nums[i] != 0) {
            nums[write++] = nums[i];
        }
    }

    while (write < n) {
        nums[write++] = 0;
    }
}

Java
public static void applyOperations(int[] nums) {
        int n = nums.length;

        // Step 1: Apply operations
        for (int i = 0; i < n - 1; i++) {
            if (nums[i] == nums[i + 1]) {
                nums[i] *= 2;
                nums[i + 1] = 0;
            }
        }

        // Step 2: Shift non-zero elements in-place
        int write = 0;
        for (int i = 0; i < n; i++) {
            if (nums[i] != 0) {
                nums[write++] = nums[i];
            }
        }

        while (write < n) {
            nums[write++] = 0;
        }
}

Python
def applyOperations(nums):
    n = len(nums)

    for i in range(n - 1):
        if nums[i] == nums[i + 1]:
            nums[i] *= 2
            nums[i + 1] = 0

    write = 0
    for i in range(n):
        if nums[i] != 0:
            nums[write] = nums[i]
            write += 1

    while write < n:
        nums[write] = 0
        write += 1

    return nums

Javascript
function solve(stdin) {
    const nums = stdin.trim().split(/\s+/).map(Number);
    const n = nums.length;

    // Step 1: Apply operations
    for (let i = 0; i < n - 1; i++) {
        if (nums[i] === nums[i + 1]) {
            nums[i] *= 2;
            nums[i + 1] = 0;
        }
    }

    // Step 2: Shift non-zero elements in-place
    let write = 0;
    for (let i = 0; i < n; i++) {
        if (nums[i] !== 0) {
            nums[write++] = nums[i];
        }
    }

    while (write < n) {
        nums[write++] = 0;
    }

    console.log(nums.join(" "));
}

Time complexity - O(n)

The entire logic runs in linear time. First, we go through the array once to apply the doubling-and-zeroing operations. Then, we make a second pass to shift all the non-zero elements to the front and finally fill the rest with zeros. All of these steps happen in a single sweep or two at most — no nested loops, no extra processing. So overall, the time complexity is O(n) where n is the length of the array.

Space Complexity - O(n)

We don’t use any extra data structures like additional arrays. Everything is done directly within the input array itself. Just a few variables are used to keep track of indices. Since we’re not consuming any space that grows with the input size, the space complexity is O(1) — constant space.

Similar Questions

Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. The relative order of the elements should be kept the same. Then return the number of unique elements in nums

Given an integer array nums, move all 0's to the end of it while maintaining the relative order of the non-zero elements.