Python Program to Find GCD Using Recursion
def gcd(a, b): return a if b == 0 else gcd(b, a % b) which calls itself until the remainder is zero.Examples
How to Think About It
% to reduce the problem size. If the second number is zero, the first number is the GCD. Otherwise, we call the function again with the second number and the remainder of the first number divided by the second.Algorithm
Code
def gcd(a, b): if b == 0: return a else: return gcd(b, a % b) print(gcd(48, 18))
Dry Run
Let's trace gcd(48, 18) through the code
Initial call
gcd(48, 18) checks if 18 == 0 (false), calls gcd(18, 48 % 18)
Second call
gcd(18, 12) checks if 12 == 0 (false), calls gcd(12, 18 % 12)
Third call
gcd(12, 6) checks if 6 == 0 (false), calls gcd(6, 12 % 6)
Fourth call
gcd(6, 0) checks if 0 == 0 (true), returns 6
Return values
Each call returns 6 back up the chain to the original call
| Call | a | b | a % b | Return |
|---|---|---|---|---|
| 1 | 48 | 18 | 12 | gcd(18, 12) |
| 2 | 18 | 12 | 6 | gcd(12, 6) |
| 3 | 12 | 6 | 0 | gcd(6, 0) |
| 4 | 6 | 0 | - | 6 |
Why This Works
Step 1: Base case
When the second number b is zero, the first number a is the GCD, so the function returns a.
Step 2: Recursive call
If b is not zero, the function calls itself with b and the remainder of a divided by b, reducing the problem size.
Step 3: Repeating until base case
This process repeats, shrinking the numbers until the remainder is zero, ensuring the GCD is found.
Alternative Approaches
def gcd_iterative(a, b): while b != 0: a, b = b, a % b return a print(gcd_iterative(48, 18))
import math print(math.gcd(48, 18))
Complexity: O(log(min(a, b))) time, O(log(min(a, b))) space
Time Complexity
Each recursive call reduces the problem size roughly by the remainder, which decreases quickly, leading to a logarithmic time complexity.
Space Complexity
The recursion stack grows with the number of calls, which is proportional to the logarithm of the smaller input.
Which Approach is Fastest?
The built-in math.gcd is fastest and most optimized, followed by the iterative approach which avoids recursion overhead.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Recursive gcd | O(log(min(a,b))) | O(log(min(a,b))) | Learning recursion and simplicity |
| Iterative gcd | O(log(min(a,b))) | O(1) | Avoiding recursion overhead |
| math.gcd | O(log(min(a,b))) | O(1) | Best performance and simplicity |
% to reduce the problem size in each recursive call.