Remove Duplicates from Sorted Array

EasyArrays · Two Pointers🧩 Array ManipulationLeetCode #26 ↗Updated

Problem

You are given nums sorted in non-decreasing order. Rearrange it in-place so that each distinct value appears exactly once at the front, in the original order, and return that count k. Only nums[0..k-1] is checked; whatever sits after it does not matter.
Inputnums = [1,1,2]Outputk = 2, nums starts with [1,2]
Inputnums = [0,0,1,1,1,2,2,3,3,4]Outputk = 5, nums starts with [0,1,2,3,4]

1 ≤ n ≤ 3·104  ·  -100 ≤ nums[i] ≤ 100  ·  sorted non-decreasing  ·  O(1) extra space

Try it yourself

Java
class Solution {
    public int removeDuplicates(int[] nums) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Because the array is sorted, duplicates are adjacent: a value is new exactly when it differs from the last value kept. A write pointer packs new values to the front.
PatternArray Manipulation

Instinct "In place", "O(1) extra space" or "one pass" over an array? Think write pointer, reversal, prefix/suffix passes or using indices as storage.

Memory hack Read fast, write slow, reverse to rotate, and let the index be the hash.

Open the Array Manipulation guide →

Approaches

Brute ForceShift Left on Every Duplicate

Time O(n2)Space O(1)

Walk the array; whenever nums[i] equals its predecessor, delete it by shifting everything after it one slot left and shrinking the logical length. This is what “remove” means on a plain array.

Java
public int removeDuplicates(int[] nums) {
    int len = nums.length; // logical length after deletions
    int i = 1;
    while (i < len) {
        if (nums[i] == nums[i - 1]) {
            // delete nums[i] by shifting the tail left
            for (int j = i; j < len - 1; j++) {
                nums[j] = nums[j + 1];
            }
            len--;
        } else {
            i++;
        }
    }
    return len;
}

In-place, but each deletion is O(n), so many duplicates make it quadratic.

At a glance

LevelApproachTimeSpace
Brute ForceShift Left on Every DuplicateO(n2)O(1)
BetterCopy Uniques to a BufferO(n)O(n)
OptimalRead/Write Two PointersO(n)O(1)
Common pitfalls
  • Starting write at 0 — nums[0] is always kept, so the first slot to fill is 1.
  • Returning write - 1 or the last index instead of the count.
  • Reaching for a HashSet — it ignores the sorted order and uses O(n) memory.
Interview tips
  • Point out that sortedness makes duplicates adjacent — that's the whole problem.
  • State the invariant: nums[0..write-1] is strictly increasing and complete so far.
  • Offer the “at most k copies” generalisation to show depth.
Pattern
Read/write (fast–slow) pointers → compact a sorted array in-place, keeping elements that pass a test against the last kept one.
My notes saved in this browser