2Brute2Best
🔥0

Climbing Stairs

Easy·LeetCode #70Basic Anchor
LeetCode
30-Second Mental ModelDP 1D — Fibonacci-style (two variables)
Complexity:O(2^N)→O(N)
Key Insight

Step i reads only steps i − 1 and i − 2. So we never need the whole memo: only the last two answers matter. Keep two variables, prev2 (ways to reach step i − 2) and prev1 (ways to reach step i − 1). Each new step is prev1 + prev2, and then both variables move up one step. The space is O(1).

Core Validity Invariant

The count for step i is exactly the count for step i − 1 plus the count for step i − 2, because the last move is either a 1-step or a 2-step.

01

Problem

A staircase has n steps. You start on the ground, below step 1, and you want to reach step n, the top.

Each move takes you up 1 step or 2 steps. Count the different ways to reach the top.

Two ways are different when their moves are in a different order. For example, 1 + 2 and 2 + 1 are two different ways, even though both reach the top.

Input

An integer n, the number of steps.

Output

One integer: the number of different ways to reach step n.

Example 1
Input: n = 2
Output: 2

Two ways: 1 + 1, or one 2-step. Both reach the top.

Example 2
Input: n = 3
Output: 3

Three ways: 1 + 1 + 1, 1 + 2 and 2 + 1.

Constraints
  • • 1 ≤ n ≤ 45
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    If I am standing on step 5, what was my last move? Could I have come from step 4, or from step 3?

  2. 2.

    How many ways are there to reach step 1? And to reach step 2?

  3. 3.

    Do I need the full list of moves, or only how many lists there are?

  4. 4.

    To find the answer for step 6, which earlier answers do I need? Do I need the answers for all of steps 1 to 4?

  5. 5.

    The next answer only reads two earlier answers. Could I keep just those two numbers?

03

Brute force approach

04

Better approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceRecursive ways(i) = ways(i−1) + ways(i−2), with no memoryO(2^N)O(N)
BetterThe same recursion, but store each ways(i) the first time it is computedO(N)O(N)
OptimalKeep only the last two answers in two variables and build up from step 3O(N)O(1)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “how many ways”The question asks for a count, not the list of moves. Build the count step by step, and do not list the paths.
  • “climb 1 or 2 steps”The choice at each step only looks back one or two steps, so the answer for step i depends only on steps i − 1 and i − 2.
  • “reach the top”The top is a fixed target, step n. Fill the answers from the bottom up to n.
Count the ways to reach step n+each move is 1 or 2 steps+answer(i) depends only on answer(i − 1) and answer(i − 2)→DP 1D — Fibonacci-style (two variables)

This is the anchor of the Fibonacci-style sub-pattern: the answer at step i depends on the two steps before it, so the table can shrink to two variables. Each move only looks back one or two steps, and the count itself is a plain sum with no cost or rule to check. Min Cost Climbing Stairs keeps the same two-step shape but adds a cost to each step, and Decode Ways adds a rule that decides when a step can be used at all.

10

Don't make this mistake

Pattern confusion: listing every path (backtracking)
✗ void dfs(int left, vector<int>& path, vector<vector<int>>& out) { if (left == 0) { out.push_back(path); return; } for (int s = 1; s <= 2 && s <= left; s++) { path.push_back(s); dfs(left - s, path, out); path.pop_back(); } } // ... return out.size();
✓ int prev2 = 1, prev1 = 2; for (int i = 3; i <= n; i++) { int cur = prev1 + prev2; prev2 = prev1; prev1 = cur; } return prev1;

The problem asks for a count, but this search builds every list of moves. For n = 5 it makes 20 calls and writes out 8 lists. The DP fills 5 cells, one per step. For n = 45 there are 1836311903 lists, so listing them is impossible. You only need the count, so you never need to build a list.

Wrong base case for two steps
✗ if (n <= 2) return 1;
✓ if (n <= 2) return n;

Two steps can be climbed as 1 + 1 or as one 2-step, which is 2 ways, not 1. With the wrong base, n = 2 returns 1. If the same wrong base sits in the recursion (if (i <= 2) return 1;), then n = 3 gives ways(2) + ways(1) = 1 + 1 = 2 instead of 3.

Loop starts one step too early
✗ int prev2 = 1, prev1 = 2; for (int i = 2; i <= n; i++) { int cur = prev1 + prev2; prev2 = prev1; prev1 = cur; }
✓ int prev2 = 1, prev1 = 2; for (int i = 3; i <= n; i++) { int cur = prev1 + prev2; prev2 = prev1; prev1 = cur; }

The two starting values already cover steps 1 and 2. Starting at i = 2 adds an extra step. For n = 3 the wrong loop runs twice, producing 3 and then 5, and returns 5. The answer is 3.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like DP — 1D Linear translate into production architectures and low-level memory mechanics.