Skip to content
← All posts

Remove Element: In-Place Array Filtering

4 min read
leetcodeproblemeasyarraystwo-pointers

LeetCode Remove Element (problem 27) asks you to remove all occurrences of a given value from an array in-place and return the count of remaining elements. The order of the remaining elements does not matter.

This is one of the first problems where you encounter the read-write pointer pattern. It is simple, but the technique behind it shows up in dozens of harder problems. Getting it into your fingers now pays off later.

The problem

Given nums = [0, 1, 2, 2, 3, 0, 4, 2] and val = 2, remove all 2s in-place and return k = 5. The first k positions of the array should hold the values [0, 1, 3, 0, 4] in any order. What sits beyond index k - 1 does not matter.

0011222334054627writeread
Input array with val = 2. Blue cells are kept, red cells are removed. Both pointers start at index 0.

The function signature returns an integer k. The judge then checks only the first k elements of the modified array.

The approach: read-write pointer

The idea is clean. You walk through the array with a read pointer. Every time you find a value that is not val, you copy it to the write pointer position and advance write. When read reaches the end, write tells you how many elements you kept.

  • read scans every element, one by one
  • write only advances when you copy a keeper
  • Elements equal to val are simply skipped by read, so they get overwritten by future keepers

The write pointer always trails behind or stays even with read. By the time read finishes, everything at indices 0 through write - 1 is a non-val element.

def remove_element(nums: list[int], val: int) -> int:
    write = 0
    for read in range(len(nums)):
        if nums[read] != val:
            nums[write] = nums[read]
            write += 1
    return write

That is the entire solution. One pass, no extra memory, no tricky index math.

You do not need to "delete" anything. You just overwrite the front of the array with the values you want to keep. The leftover values past index k - 1 are irrelevant to the judge.

Visual walkthrough

Trace through nums = [0, 1, 2, 2, 3, 0, 4, 2] with val = 2. Watch how the write pointer only moves forward when read finds a non-val element.

Start: read sees nums[0] = 0. Not val, so copy to write position.

01223042writeread

nums[read] is 0, which is not 2. Write nums[0] = 0, advance both pointers.

Step 1: read sees nums[1] = 1. Not val, copy it.

01223042writeread

nums[read] is 1, not 2. Write nums[1] = 1, advance both.

Step 2: read sees nums[2] = 2. That is val, skip it.

01223042writeread

nums[read] is 2 (the value to remove). Only advance read, write stays.

Step 3: read sees nums[3] = 2. Val again, skip.

01223042writeread

Another 2. Advance read only.

Step 4: read sees nums[4] = 3. Not val, copy to write position.

01323042writeread

nums[read] is 3. Write nums[2] = 3, advance both.

Step 5: read sees nums[5] = 0. Not val, copy it.

01303042writeread

nums[read] is 0. Write nums[3] = 0, advance both.

Step 6: read sees nums[6] = 4. Not val, copy it.

01304042writeread

nums[read] is 4. Write nums[4] = 4, advance both.

Step 7: read sees nums[7] = 2. Val, skip. read reaches the end.

01304042writeread

nums[read] is 2. Only advance read. read is now past the last index.

Done: write = 5, so k = 5. The first 5 elements are the result.

01304042writeread

Return k = 5. The first 5 positions [0, 1, 3, 0, 4] contain all non-val elements.

Notice how write falls behind read every time a 2 is skipped. By the end, write sits at 5, which is exactly the count of non-2 elements. The first 5 positions of the array contain [0, 1, 3, 0, 4].

Complexity

MetricValue
TimeO(n), one pass through the array
SpaceO(1), no extra data structures

Every element is read exactly once. At most n writes happen (when no elements match val). There is no nested loop and no auxiliary storage.

The building blocks

This problem decomposes into one core reusable brick.

Read-write pointer (in-place filtering)

The read pointer scans the input. The write pointer marks where the next valid element should go. When the read pointer finds an element worth keeping, it gets copied to the write position. When it finds one to discard, only read advances.

write = 0
for read in range(len(nums)):
    if nums[read] != val:
        nums[write] = nums[read]
        write += 1
return write

This micro-pattern is the foundation of many in-place array transformations:

  • Remove Duplicates from Sorted Array (LeetCode 26) uses the same read-write structure, but the filter condition is nums[read] != nums[write - 1] instead of != val.
  • Move Zeroes (LeetCode 283) filters out zeroes the same way, then fills the remaining positions with 0.
  • Sort Colors (LeetCode 75) extends the idea to three write targets instead of one, using three pointers instead of two.

Once you can write the read-write pointer loop from memory, these problems become variations on the same skeleton.

Edge cases

Empty array. If nums has length 0, the loop body never runs and write stays at 0. You return 0. No special handling needed.

All elements equal val. Read advances through every element but write never moves. You return 0 and the first 0 elements are checked, which is nothing.

No elements equal val. Every element passes the filter. Write advances in lockstep with read, so you return len(nums). The array is unchanged.

Single element. If nums = [val], return 0. If nums = [anything_else], return 1. The loop handles both correctly without edge-case branches.

From understanding to recall

This problem is easy to understand on first read. The challenge is not comprehension. It is being able to write the solution from scratch under pressure without pausing to think about pointer placement.

The read-write pointer is a building block you will reach for over and over. Each time you encounter it in a new problem (remove duplicates, move zeroes, partition arrays), you reinforce the same muscle memory. The goal is to make the loop structure automatic so your mental energy goes toward the filter condition, not the pointer mechanics.

Practice writing the solution on a blank screen. Once you can produce it without referencing anything, space out your reviews. Come back in a few days, then a week. That is when the pattern moves from short-term recall to permanent skill.

Related posts