LeetCopilot Logo
LeetCopilot
LeetCode Pattern/Two Pointers/Two Pointers for In-Place Array Manipulation: Remove, Partition, and Swap

Two Pointers for In-Place Array Manipulation: Remove, Partition, and Swap

LeetCopilot Team
Dec 9, 2025
15 min read
Two PointersIn-PlaceArray ManipulationRead Write PatternInterview Prep
Master the read/write pointer pattern for O(1) space array manipulation. Learn when to use in-place techniques, how to preserve order, and the patterns that appear in dozens of problems.

You're solving "Remove Duplicates from Sorted Array." The problem says: "Do this in-place without extra space."

Your first instinct: create a new array, copy unique elements. Simple, but uses O(n) space.

Then you realize: "I can use two pointers to modify the array in-place!"

Suddenly, you've transformed an O(n) space solution into O(1) space. You've unlocked a fundamental technique.

This is the power of in-place manipulation with two pointers. It's not just about saving space—it's about understanding how to build new arrays within old ones using clever pointer management.

This comprehensive guide will teach you the read/write pointer pattern, when to use in-place techniques, how to preserve order, and the patterns that appear in dozens of LeetCode problems.

TL;DR

In-place manipulation pattern:

  • Read pointer: Scans through array
  • Write pointer: Marks where to place next valid element
  • Result: First write elements contain the answer

Use when:

  • Problem requires O(1) space
  • Says "in-place" or "without extra space"
  • Removing, partitioning, or rearranging elements

Template:

python
write = 0
for read in range(len(arr)):
    if is_valid(arr[read]):
        arr[write] = arr[read]
        write += 1
return write  # New length

Time: O(n), Space: O(1)

What Is In-Place Manipulation?

The Core Concept

Instead of creating a new array, we overwrite the existing array with the result, using two pointers:

Visual:

code
Original: [1, 1, 2, 2, 3]
           R W              Read=1, Write=0, arr[0]=1, W++

[1, 1, 2, 2, 3]
              R W           Read=1, duplicate, skip

[1, 2, 2, 2, 3]
                 R   W      Read=2, arr[1]=2, W++

[1, 2, 2, 2, 3]
                    R   W   Read=2, duplicate, skip

[1, 2, 3, 2, 3]
                       R  W Read=3, arr[2]=3, W++

Result: [1, 2, 3, ?, ?]
                 W
Length = 3

Why It Works

Key insight: We're building a new array in the same memory, overwriting values we no longer need.

Invariant: arr[0...write-1] always contains valid elements processed so far.

The Universal Template

Python Template

python
def in_place_template(arr):
    """
    Template for in-place array manipulation.
    
    Args:
        arr: Array to modify in-place
    
    Returns:
        New length (number of valid elements)
    """
    # Edge case
    if not arr:
        return 0
    
    # Write pointer starts at 0 or 1 (depending on problem)
    write = 0
    
    # Read pointer scans entire array
    for read in range(len(arr)):
        # Check if current element is valid
        if is_valid(arr[read]):
            # Write it to write position
            arr[write] = arr[read]
            # Move write pointer
            write += 1
    
    # Return new length
    return write

JavaScript Template

javascript
function inPlaceTemplate(arr) {
    if (arr.length === 0) return 0;
    
    let write = 0;
    
    for (let read = 0; read < arr.length; read++) {
        if (isValid(arr[read])) {
            arr[write] = arr[read];
            write++;
        }
    }
    
    return write;
}

Java Template

java
public int inPlaceTemplate(int[] arr) {
    if (arr.length == 0) return 0;
    
    int write = 0;
    
    for (int read = 0; read < arr.length; read++) {
        if (isValid(arr[read])) {
            arr[write] = arr[read];
            write++;
        }
    }
    
    return write;
}

Pattern 1: Remove Duplicates from Sorted Array

Problem

Remove duplicates in-place, return new length.

Solution

python
def removeDuplicates(nums: List[int]) -> int:
    """
    LeetCode #26: Remove Duplicates from Sorted Array
    
    Time: O(n)
    Space: O(1)
    """
    if not nums:
        return 0
    
    # Write starts at 1 (first element always unique)
    write = 1
    
    for read in range(1, len(nums)):
        # If different from previous, it's unique
        if nums[read] != nums[read - 1]:
            nums[write] = nums[read]
            write += 1
    
    return write

Why It Works

Sorted property: Duplicates are adjacent.

Read pointer: Scans for new unique values.

Write pointer: Marks where to place next unique value.

Result: First write elements are all unique.

See detailed explanation: Remove duplicates pattern

Pattern 2: Remove Element

Problem

Remove all instances of a value in-place.

Solution

python
def removeElement(nums: List[int], val: int) -> int:
    """
    LeetCode #27: Remove Element
    
    Time: O(n)
    Space: O(1)
    """
    write = 0
    
    for read in range(len(nums)):
        # Keep elements that are NOT equal to val
        if nums[read] != val:
            nums[write] = nums[read]
            write += 1
    
    return write

Why It Works

Read pointer: Scans all elements.

Write pointer: Only advances for valid elements (not equal to val).

Result: First write elements don't contain val.

Pattern 3: Move Zeroes

Problem

Move all zeros to the end while preserving relative order of non-zeros.

Solution

python
def moveZeroes(nums: List[int]) -> None:
    """
    LeetCode #283: Move Zeroes
    
    Time: O(n)
    Space: O(1)
    """
    write = 0
    
    # Phase 1: Copy all non-zeros to front
    for read in range(len(nums)):
        if nums[read] != 0:
            nums[write] = nums[read]
            write += 1
    
    # Phase 2: Fill remaining with zeros
    for i in range(write, len(nums)):
        nums[i] = 0

Why It Works

Two phases:

  1. Copy non-zeros to front (preserves order)
  2. Fill rest with zeros

Order preservation: See Move zeroes order

Optimized One-Pass Version

python
def moveZeroes(nums: List[int]) -> None:
    """
    One-pass version with swap optimization.
    """
    write = 0
    
    for read in range(len(nums)):
        if nums[read] != 0:
            nums[write] = nums[read]
            # Zero out the read position if we've moved past it
            if write != read:
                nums[read] = 0
            write += 1

Pattern 4: Remove Duplicates II (Allow K Duplicates)

Problem

Remove duplicates such that each element appears at most twice.

Solution

python
def removeDuplicates(nums: List[int]) -> int:
    """
    LeetCode #80: Remove Duplicates from Sorted Array II
    
    Allow at most 2 duplicates.
    
    Time: O(n)
    Space: O(1)
    """
    if len(nums) <= 2:
        return len(nums)
    
    # Write starts at 2 (first two always valid)
    write = 2
    
    for read in range(2, len(nums)):
        # Compare with element 2 positions back
        if nums[read] != nums[write - 2]:
            nums[write] = nums[read]
            write += 1
    
    return write

Why It Works

Key insight: Compare with element k positions back to allow k duplicates.

For k=2: nums[read] != nums[write - 2] ensures at most 2 duplicates.

Generalization:

python
def removeDuplicatesK(nums, k):
    if len(nums) <= k:
        return len(nums)
    
    write = k
    for read in range(k, len(nums)):
        if nums[read] != nums[write - k]:
            nums[write] = nums[read]
            write += 1
    
    return write

Pattern 5: Sort Colors (Dutch National Flag)

Problem

Sort array of 0s, 1s, and 2s in-place.

Solution

python
def sortColors(nums: List[int]) -> None:
    """
    LeetCode #75: Sort Colors
    
    Three-way partitioning with three pointers.
    
    Time: O(n)
    Space: O(1)
    """
    # Three pointers
    low = 0      # Boundary for 0s
    mid = 0      # Current element
    high = len(nums) - 1  # Boundary for 2s
    
    while mid <= high:
        if nums[mid] == 0:
            # Swap with low boundary
            nums[low], nums[mid] = nums[mid], nums[low]
            low += 1
            mid += 1
        elif nums[mid] == 1:
            # Already in correct position
            mid += 1
        else:  # nums[mid] == 2
            # Swap with high boundary
            nums[mid], nums[high] = nums[high], nums[mid]
            high -= 1
            # Don't increment mid (need to check swapped element)

Why It Works

Three regions:

  • [0, low): All 0s
  • [low, mid): All 1s
  • (high, n): All 2s
  • [mid, high]: Unprocessed

Invariant maintained at each step.

Pattern 6: Partition Array

Problem

Partition array so all elements less than x come before elements greater than or equal to x.

Solution

python
def partition(nums: List[int], x: int) -> int:
    """
    Partition array around value x.
    
    Time: O(n)
    Space: O(1)
    """
    write = 0
    
    # Phase 1: Move all elements < x to front
    for read in range(len(nums)):
        if nums[read] < x:
            nums[write], nums[read] = nums[read], nums[write]
            write += 1
    
    return write  # Partition point

Stable Partition (Preserve Order)

python
def stablePartition(nums: List[int], x: int) -> int:
    """
    Partition while preserving relative order.
    """
    write = 0
    
    # Copy elements < x to front
    for read in range(len(nums)):
        if nums[read] < x:
            nums[write] = nums[read]
            write += 1
    
    # Copy elements >= x to rest
    for read in range(len(nums)):
        if nums[read] >= x:
            nums[write] = nums[read]
            write += 1
    
    return write

When to Use In-Place Manipulation

✅ Use When:

  1. Problem requires O(1) space
  2. Says "in-place" or "without extra space"
  3. Removing elements from array
  4. Partitioning array
  5. Rearranging elements

❌ Don't Use When:

  1. Need to preserve original array
  2. Order matters and can't be maintained
  3. Removing elements breaks algorithm logic
  4. Extra space is allowed and simpler

Common Mistakes

Mistake 1: Starting Write at Wrong Position

python
# WRONG for Remove Duplicates
write = 0  # Should be 1
for read in range(len(nums)):
    if nums[read] != nums[read - 1]:  # Crashes when read=0!

Fix: Start write at 1, read at 1 for Remove Duplicates.

Mistake 2: Not Filling Remaining Elements

python
# WRONG for Move Zeroes
write = 0
for num in nums:
    if num != 0:
        nums[write] = num
        write += 1
# Missing: fill rest with zeros!

Fix: Add second loop to fill zeros.

Mistake 3: Incorrect Comparison

python
# WRONG
if nums[read] != nums[write - 1]:  # Should compare with read - 1

Fix: Compare with previous element in original array.

Advanced Techniques

Technique 1: Two-Pass for Complex Operations

python
def complexOperation(nums):
    # Pass 1: Process one type
    write = 0
    for read in range(len(nums)):
        if condition1(nums[read]):
            nums[write] = nums[read]
            write += 1
    
    # Pass 2: Process another type
    for read in range(len(nums)):
        if condition2(nums[read]):
            nums[write] = nums[read]
            write += 1

Technique 2: Swap Instead of Overwrite

python
def partitionWithSwap(nums, x):
    write = 0
    for read in range(len(nums)):
        if nums[read] < x:
            # Swap instead of overwrite
            nums[write], nums[read] = nums[read], nums[write]
            write += 1

Use swap when: You need to preserve all elements (just rearrange).

Use overwrite when: You're removing elements.

Practice Problems

Master in-place manipulation with these:

Beginner:

  1. Remove Duplicates (#26) - basic read/write
  2. Remove Element (#27) - filter elements
  3. Move Zeroes (#283) - stable partition

Intermediate:
4. Remove Duplicates II (#80) - allow k duplicates
5. Sort Colors (#75) - three-way partition
6. Partition Labels (#763) - complex partitioning

Advanced:
7. Remove Covered Intervals (#1288) - sorting + in-place
8. Merge Sorted Array (#88) - in-place merge
9. Squares of Sorted Array (#977) - two pointers + in-place

Complexity Analysis

Time Complexity: O(n)

  • Single pass through array
  • Constant work per element

Space Complexity: O(1)

  • Only use pointer variables
  • Modify array in-place

Comparison with extra space:

  • Extra space: O(n) time, O(n) space
  • In-place: O(n) time, O(1) space ✓

FAQ

Q: When should I use in-place vs creating a new array?

A: Use in-place when problem requires O(1) space or explicitly says "in-place." Otherwise, creating a new array is often simpler.

Q: How do I preserve order?

A: Use read/write pattern (copy valid elements in order), not swapping. See Move zeroes order.

Q: What if I need the original array later?

A: You can't use in-place manipulation. Create a new array or copy the original first.

Q: Can I use this on linked lists?

A: Yes, but the pattern is different (modify pointers, not values). See linked list pitfalls.

Conclusion

In-place array manipulation with two pointers is a fundamental technique for O(1) space solutions.

Key principles:

  • Read pointer scans array
  • Write pointer marks where to place valid elements
  • Invariant: arr[0...write-1] contains result
  • Return write pointer as new length

The template:

python
write = 0
for read in range(len(arr)):
    if is_valid(arr[read]):
        arr[write] = arr[read]
        write += 1
return write

When to use:

  • O(1) space required
  • "In-place" in problem statement
  • Removing or rearranging elements

Patterns:

  • Remove duplicates: Compare with previous
  • Remove element: Filter by value
  • Move zeros: Two-phase (copy + fill)
  • Partition: Swap or copy by condition

Master this pattern, and you'll handle all in-place array problems with confidence. For more patterns, see the complete two pointers guide and read/write pointer pattern.

Next time you see "in-place," think: read and write pointers.

Want to Practice LeetCode Smarter?

LeetCopilot is a free browser extension that enhances your LeetCode practice with AI-powered hints, personalized study notes, and realistic mock interviews — all designed to accelerate your coding interview preparation.

Also compatible with Edge, Brave, and Opera

Related Tutorials