In-Place Filtering and Squaring of Sorted Arrays via Two-Pointer Techniques

Problem 1: In-Place Removal of Target Value

Given an integer array nums and a integer val, remove every occurrence of val in place. The relative order of the remaining elements may change. Return the new length k such that the first k slots of nums contain all elements that are not equal to val. The rest of the array is ignored by the judge.

Constraints

  • 0 ≤ nums.length ≤ 100
  • 0 ≤ nums[i] ≤ 50
  • 0 ≤ val ≤ 100

Two-Pointer Strategy

Keep a write pointer (w) and a scan pointer (s). The scan pointer iterates through every element; whenever the current element is not the target value, it is copied to the position indicated by the write pointer, which then advances. At the end, w equals the count of surviving elements.

int removeTarget(vector<int>& nums, int val) {
    int w = 0;                       // next position to keep
    for (int s = 0; s < nums.size(); ++s) {
        if (nums[s] != val) {
            nums[w++] = nums[s];     // keep it
        }
    }
    return w;                        // new logical length
}

Problem 2: Squaring a Sorted Array in Linear Time

Given a integer array nums sorted in non-decreasing order, return a new array consisting of the squares of each number, also sorted in non-decreasing order.

Constraints

  • 1 ≤ nums.length ≤ 10<sup>4</sup>
  • -10<sup>4</sup> ≤ nums[i] ≤ 10<sup>4</sup>

Optimal Two-Pointer Approach

The largest squared value must come from either the leftmost (most negative) or the rightmost (largest positive) element. Maintain two indices—L starting at 0 and R starting at nums.size()-1—and fill the result array from the back.

vector<int> squaredSorted(vector<int>& nums) {
    int n = nums.size();
    vector<int> res(n);
    int pos = n - 1;                 // next slot to fill

    for (int L = 0, R = n - 1; L <= R;) {
        long leftSq  = 1L * nums[L] * nums[L];
        long rightSq = 1L * nums[R] * nums[R];

        if (leftSq > rightSq) {
            res[pos--] = (int)leftSq;
            ++L;
        } else {
            res[pos--] = (int)rightSq;
            --R;
        }
    }
    return res;
}

Key observations:

  • The loop condition L <= R ensures the middle element is handled exactly once.
  • Using pos-- inside the assignment shortens the code without sacrificing clarity.
  • Long arithmetic prevents overflow when squaring -10<sup>4</sup>.

Tags: two-pointer array-manipulation in-place-algorithm C++

Posted on Sat, 09 May 2026 15:57:34 +0000 by jd57