easy questions
This commit is contained in:
102
backend/data/questions/climbing-stairs.yaml
Normal file
102
backend/data/questions/climbing-stairs.yaml
Normal file
@@ -0,0 +1,102 @@
|
||||
title: Climbing Stairs
|
||||
slug: climbing-stairs
|
||||
difficulty: easy
|
||||
leetcode_id: 70
|
||||
leetcode_url: https://leetcode.com/problems/climbing-stairs/
|
||||
categories:
|
||||
- dynamic-programming
|
||||
- math
|
||||
patterns:
|
||||
- dynamic-programming
|
||||
|
||||
description: |
|
||||
You are climbing a staircase. It takes n steps to reach the top.
|
||||
|
||||
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
|
||||
|
||||
constraints: |
|
||||
- 1 <= n <= 45
|
||||
|
||||
examples:
|
||||
- input: "n = 2"
|
||||
output: "2"
|
||||
explanation: "Two ways: (1+1) or (2)"
|
||||
- input: "n = 3"
|
||||
output: "3"
|
||||
explanation: "Three ways: (1+1+1), (1+2), (2+1)"
|
||||
|
||||
explanation:
|
||||
approach: |
|
||||
1. Recognize this follows the Fibonacci pattern
|
||||
2. ways(n) = ways(n-1) + ways(n-2)
|
||||
3. From step n-1, we can take 1 step to reach n
|
||||
4. From step n-2, we can take 2 steps to reach n
|
||||
5. Base cases: ways(1) = 1, ways(2) = 2
|
||||
|
||||
intuition: |
|
||||
At any step, you either got there by taking 1 step from the previous position
|
||||
or 2 steps from two positions back. This gives us the recurrence relation.
|
||||
|
||||
This is essentially the Fibonacci sequence! The number of ways to reach step n
|
||||
equals the sum of ways to reach steps n-1 and n-2.
|
||||
|
||||
common_pitfalls:
|
||||
- title: Using recursion without memoization
|
||||
description: |
|
||||
Naive recursion recalculates the same subproblems repeatedly, leading to
|
||||
exponential time complexity. Either use memoization or iterative DP.
|
||||
wrong_approach: "return climb(n-1) + climb(n-2) without caching"
|
||||
correct_approach: "Use bottom-up DP or memoize recursive calls"
|
||||
|
||||
- title: Off-by-one in base cases
|
||||
description: |
|
||||
Carefully define base cases. There's 1 way to stay at ground (step 0),
|
||||
1 way to reach step 1, and 2 ways to reach step 2.
|
||||
|
||||
key_takeaways:
|
||||
- Many counting problems follow Fibonacci-like patterns
|
||||
- Convert recursion to iteration for O(1) space
|
||||
- Bottom-up DP avoids stack overflow for large inputs
|
||||
- Recognize overlapping subproblems as a DP signal
|
||||
|
||||
time_complexity: "O(n)"
|
||||
space_complexity: "O(1)"
|
||||
complexity_explanation: |
|
||||
Time: We compute n states, each in O(1).
|
||||
Space: Only track two previous values (space-optimized DP).
|
||||
|
||||
solutions:
|
||||
- approach_name: Space-Optimized DP (Optimal)
|
||||
is_optimal: true
|
||||
code: |
|
||||
def climb_stairs(n: int) -> int:
|
||||
if n <= 2:
|
||||
return n
|
||||
|
||||
prev1, prev2 = 2, 1
|
||||
for i in range(3, n + 1):
|
||||
current = prev1 + prev2
|
||||
prev2 = prev1
|
||||
prev1 = current
|
||||
|
||||
return prev1
|
||||
explanation: |
|
||||
Track only the two previous values since that's all we need.
|
||||
Equivalent to computing the nth Fibonacci number.
|
||||
|
||||
- approach_name: Recursive with Memoization
|
||||
is_optimal: false
|
||||
code: |
|
||||
from functools import lru_cache
|
||||
|
||||
def climb_stairs(n: int) -> int:
|
||||
@lru_cache(maxsize=None)
|
||||
def dp(step: int) -> int:
|
||||
if step <= 2:
|
||||
return step
|
||||
return dp(step - 1) + dp(step - 2)
|
||||
|
||||
return dp(n)
|
||||
explanation: |
|
||||
Top-down approach with memoization.
|
||||
Uses O(n) space for the cache and recursion stack.
|
||||
Reference in New Issue
Block a user