◀ THE GRIND — ARRAYS & HASHING

First Missing Positive

The drill: The smallest positive integer an unsorted array is missing — with the real fight in the bounds: linear time, constant extra space. Length n pins the answer inside 1..n+1, which is exactly what lets the array double as its own hash table.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

An unsorted list of integers sits in front of you, some negative, some zero, some repeated, and the job is to name the smallest positive whole number nowhere among them.

Nothing about the order matters and nothing needs to be produced beyond that single integer. Negative values and zero never count as candidates — the hunt only cares about 1, 2, 3, and onward.

Because the array holds n entries, the missing number can never be larger than n+1, no matter how the values are scattered. That ceiling is what keeps the drill solvable inside a strict linear-time, constant-space budget.

EX 01
nums = [1]
2
MINIMUM SIZE — THE RUN OF ONE IS COMPLETE
EX 02
nums = [-4]
1
SINGLE NEGATIVE, 1 NEVER SHOWED UP
EX 03
nums = [2, 3, 7, 1]
4
CHAIN 1..3 HOLDS, THEN SNAPS
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

Sorting answers it, and a hash set answers it faster — but one busts the time bound and the other the space bound. First shrink the battlefield: with only n values, how large can the answer possibly be?

HINT 2 THE STRUCTURE

The answer lives in 1..n+1 — the array's own index range, shifted by one. So slot i can act as the bucket for value i+1: the array can become its own hash table.

HINT 3 ONE STEP FROM THE ANSWER

While a slot holds a value in 1..n whose home slot holds something different, swap it home — each swap parks one value for good, so the work stays linear. Then the first slot whose tenant isn't i+1 names the answer; if every tenant is right, it's n+1.

COACH'S BOARD — THE PATTERN, STEP BY STEP
THE ARRAY BECOMES THE MAPPATTERN · CYCLIC SORTnums = [2, 3, 7, 1]
2
3
7
1
STEP 1

Length 4 pins the answer inside 1..5. Slot 0 holds 2, whose home is slot 1 — send it there.

STEP 1 / 9 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/first-missing-positive.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        n = len(nums)
        for i in range(n):
            # keep sending this slot's value home until the slot settles
            while 1 <= nums[i] <= n and nums[nums[i] - 1] != nums[i]:
                home = nums[i] - 1
                nums[i], nums[home] = nums[home], nums[i]
        for i in range(n):
            if nums[i] != i + 1:
                return i + 1
        return n + 1
TIME O(N)SPACE O(1)PYTHON · RACE PACE · 12 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED