A function calling itself on a smaller problem. Trust that f(n-1) works. Your job: base case + combine.
Watch calls push onto the stack, then unwind and return values bottom-up.
RecursionError: maximum recursion depth exceeded.# Without memo: O(2ⁿ) — exponential def fib(n): if n <= 1: return n return fib(n-1) + fib(n-2) # With memo: O(n) — linear def fib(n, memo={}): if n <= 1: return n if n in memo: return memo[n] memo[n] = fib(n-1, memo) + fib(n-2, memo) return memo[n] # Or use @lru_cache decorator from functools import lru_cache @lru_cache(maxsize=None) def fib(n): if n <= 1: return n return fib(n-1) + fib(n-2)
def solve(problem): # 1. Base case — ALWAYS first if is_base_case(problem): return base_answer # 2. Make smaller smaller = reduce(problem) # 3. Trust it works (leap of faith) sub_answer = solve(smaller) # 4. Combine to get current answer return combine(sub_answer, problem)
def merge_sort(arr): if len(arr) <= 1: return arr # base case mid = len(arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) return merge(left, right) def merge(l, r): res, i, j = [], 0, 0 while i < len(l) and j < len(r): if l[i] <= r[j]: res.append(l[i]); i += 1 else: res.append(r[j]); j += 1 return res + l[i:] + r[j:] # Time: O(n log n) | Space: O(n)