##### ###### ##### ### # # ### # # ###### ## ## ## ## ## ## ## # # # # # ## ##### #### ##### # # # # # # # #### ## # ## ## ## ## # # # # # ## ## # ###### ## ### # ### # ######
##### ###### ##### ### # # ### # # ###### ## ## ## ## ## ## ## # # # # # ## ##### #### ##### # # # # # # # #### ## # ## ## ## ## # # # # # ## ## # ###### ## ### # ### # ######
##### ###### ##### ### # # ### # # ###### ## ## ## ## ## ## ## # # # # # ## ##### #### ##### # # # # # # # #### ## # ## ## ## ## # # # # # ## ## # ###### ## ### # ### # ######
You've written functions. Now learn functions that call themselves. Recursion solves divide-and-conquer.
Self-calling functions
Self-referential functions
Stopping condition
Breaking down the problem
Why recursion stops
Classic recursion example
Step-by-step solution
Implement factorial
How Python tracks calls
Understanding recursion depth
Second recursion pattern
Step-by-step solution
Implement digit sum
Key patterns so far
Recursion on sequences
Step-by-step solution
Implement string reversal
Two recursive calls
Step-by-step solution
Implement Fibonacci
Why naive fib is slow
Recursion with division
Fast exponentiation
Implement fast power
Counting with recursion
Step-by-step solution
Count digits recursively
Processing sequences
Test list pattern
Recursion to find max
Step-by-step solution
Find max recursively
Two-pointer recursion
Step-by-step solution
Check palindrome
Divide and conquer
Step-by-step solution
Implement binary search
Why binary search is fast
Passing state recursively
Optimization pattern
Identify tail recursion
Choosing the right tool
Avoiding recursion bugs
Converting between styles
Choose the right approach
Tracing and fixing bugs
Caching recursive results
Test recursion proficiency
What we learned