Skip to content

Coding patternsBlind 75

Climbing Stairs

The ways to reach a stair are the ways to reach the one below plus the two below, so build the answers upward keeping only the last two. O(n) time and O(1) space, with a step-through, code in five languages and the Big O worked out from the code.

A staircase has n stairs, given as stairs. Each move climbs either 1 stair or 2 stairs. Return how many different sequences of moves take you from the bottom to the top.

Example 1

Input: stairs = 5

Output: 8

For example 1+1+1+1+1, 2+2+1, 2+1+2, 1+2+2 and 1+1+1+2. There are 8 sequences in all.

stairs
012345

Example 2

Input: stairs = 1

Output: 1

A single 1-stair move.

Example 3

Input: stairs = 4

Output: 5

1+1+1+1, 1+1+2, 1+2+1, 2+1+1 and 2+2.

  • 1 ≤ n ≤ 45
Does the order of moves matter?
Yes. 1+2 and 2+1 are two different ways.
Can a move overshoot the top?
No. The moves must end exactly on stair n.
How big can the answer get?
For n = 45 it is 1,836,311,903, which still fits in a 32-bit integer.

Think about the last move. It was either 1 stair, from stair n − 1, or 2 stairs, from stair n − 2. So the ways to reach n are the ways to reach n − 1 plus the ways to reach n − 2. The answer is built from answers to smaller versions of the same question, and those smaller answers repeat. That is dynamic programming.

Two numbers O(n)

The memo fills in from the bottom: stair 2, then 3, then 4. So skip the recursion and fill it in that order with a loop. And notice that each stair only needs the two stairs right below it. Once stair k is done, stair k − 2 is never looked at again.

So keep just two numbers: previous for the stair two below, and current for the stair one below. Start with both at 1, for stairs 0 and 1. For each next stair, the new count is previous + current. Then slide: previous takes the old current, and current takes the new count.

Why it is correct: it applies the same rule as the recursion, ways(stair) = ways(stair - 1) + ways(stair - 2), in an order where both right-hand answers are always ready.

ways
10112345
previouscurrent
previous, current
11
  1. previous, current = 1, 1 # stairs 0 and 1
  2. for i in 2 .. stairs:
  3. previous, current = current, previous + current
  4. return current

Work upward instead. Stair 0 and stair 1 each have 1 way. previous and current hold the answers for the last two stairs.

1 / 10
Solution.javasolution.pySolution.cssolution.gosolution.ts
class Solution {
// Bottom up with two numbers: build the answers from the ground floor, and
// keep only the last two, because each stair needs nothing older. O(n) time, O(1) space.
public int climbStairs(int stairs) {
// Ways to reach stair 0 and stair 1.
int previous = 1, current = 1;
for (int i = 2; i <= stairs; i++) {
int nextWays = previous + current;
previous = current;
current = nextWays;
}
return current;
}
}
Time O(n)Space O(1)Here is how we get these from the code, in four steps.
  1. 1 Find the work that repeats

    The loop body does one addition and two moves. That is a fixed job, so each run of the loop counts as 1 step.

    1. previous, current = 1, 1 # stairs 0 and 1
    2. for i in 2 .. stairs:
    3. previous, current = current, previous + current
    4. return current
  2. 2 Count the runs on Example 1

    The loop runs once for each stair from 2 to 5.

    4 runs.

    i2345
    loop runs1111
    total
    4 runs
  3. 3 Write the count for any n

    The loop goes from 2 to n:

    n − 1 runs

    Check it with Example 1: 5 − 1 = 4. That matches the count.

  4. 4 Keep only the part that grows fastest

    Drop the − 1. What is left is n.

    So the time is O(n).

  5. S Space: count the extra memory the same way

    Only previous and current are kept, whatever n is. So the space is O(1).

    previouscurrent

2,000 random n from 1 to 20. The plain recursion, the recursion with a memo and the two numbers gave the same answer every time.

Largest inputsResult
n = 45 (the most allowed), with 1,836,311,903 ways. Two numbers.Under 0.001 s, and under 0.001 MB of extra memory: just the two numbers.
n = 25. Plain recursion, about 240,000 calls.0.01 s. Each extra stair makes about 1.6 times more calls, so n = 45 would need almost 4 billion.