Home DSA GCD and LCM — Euclidean Algorithm

GCD and LCM — Euclidean Algorithm

Where developers are forged. · Structured learning · Free forever.
📍 Part of: Number Theory → Topic 2 of 5
Master GCD and LCM using the Euclidean algorithm.
🧑‍💻 Beginner-friendly — no prior DSA experience needed
In this tutorial, you'll learn:
  • GCD(a,b) = GCD(b, a mod b) — reduces to GCD(a,0)=a in O(log min(a,b)) steps.
  • LCM(a,b) = a*b / GCD(a,b) — always compute via GCD to avoid large intermediate values.
  • Extended GCD finds Bézout coefficients x,y such that ax + by = GCD(a,b).
✦ Plain-English analogy ✦ Real code with output ✦ Interview questions
⚡ Quick Answer
The Euclidean algorithm for GCD is one of the oldest algorithms known — it appears in Euclid's Elements (300 BC). The insight: if you want to find the largest tile that fits perfectly in a 252×105 room, try 105×105 tiles first. You have a 42×105 leftover strip. Now find the largest tile for 105×42. Remainder is 21×42. Then 42×21 — perfect fit! GCD(252,105) = 21. The key insight: GCD(a,b) = GCD(b, a mod b).

The Euclidean algorithm is 2300 years old, appears in Euclid's Elements (Book VII, Proposition 2), and is still one of the fastest algorithms relative to input size that exists. For 64-bit numbers, it terminates in at most 93 steps. The RSA cryptographic system — which secures most HTTPS traffic — depends on extended Euclidean to compute private keys. Every time your browser establishes a TLS connection, a variant of this algorithm runs.

The extended Euclidean algorithm (Bézout's identity: ax + by = GCD(a,b)) is the computational backbone of modular inverses. Modular inverses are the backbone of modular arithmetic. Modular arithmetic is the backbone of RSA, Diffie-Hellman, elliptic curve cryptography, and the Chinese Remainder Theorem. The entire edifice of public-key cryptography rests on an algorithm Euclid described in 300 BC.

Euclidean Algorithm for GCD

Based on the identity: GCD(a, b) = GCD(b, a mod b). Repeat until b = 0 — then GCD = a.

gcd.py · PYTHON
1234567891011121314151617181920
def gcd(a: int, b: int) -> int:
    while b:
        a, b = b, a % b
    return a

def gcd_recursive(a: int, b: int) -> int:
    return a if b == 0 else gcd_recursive(b, a % b)

def lcm(a: int, b: int) -> int:
    return a * b // gcd(a, b)  # avoid overflow: a // gcd * b

print(gcd(252, 105))    # 21
print(gcd(48, 18))      # 6
print(lcm(12, 18))      # 36
print(lcm(4, 6))        # 12

# Python 3.9+ built-in
import math
print(math.gcd(252, 105))  # 21
print(math.lcm(12, 18))    # 36
▶ Output
21
6
36
12
21
36

Why the Euclidean Algorithm is Fast

Each step reduces the larger number by at least half every two steps. More precisely, after two iterations: a mod b < a/2. This gives O(log min(a,b)) steps — for 64-bit numbers, at most ~93 iterations. The Fibonacci numbers are the worst case — GCD(F(n+1), F(n)) requires exactly n steps.

🔥
Lamé's TheoremThe number of steps in the Euclidean algorithm is at most 5 times the number of decimal digits in the smaller number. Fibonacci numbers are the worst case: GCD(F_n, F_{n-1}) takes n steps.

Extended Euclidean Algorithm

Finds integers x, y such that ax + by = GCD(a,b) (Bézout's identity). Essential for computing modular inverses.

extended_gcd.py · PYTHON
1234567891011121314151617181920212223
def extended_gcd(a: int, b: int) -> tuple[int, int, int]:
    """Returns (gcd, x, y) such that a*x + b*y = gcd."""
    if b == 0:
        return a, 1, 0
    g, x1, y1 = extended_gcd(b, a % b)
    x = y1
    y = x1 - (a // b) * y1
    return g, x, y

g, x, y = extended_gcd(35, 15)
print(f'GCD={g}, x={x}, y={y}')         # GCD=5, x=1, y=-2
print(f'Verify: 35*{x} + 15*{y} = {35*x + 15*y}')  # = 5

# Modular inverse: find x such that a*x ≡ 1 (mod m)
def mod_inverse(a: int, m: int) -> int:
    g, x, _ = extended_gcd(a % m, m)
    if g != 1:
        raise ValueError(f'{a} has no inverse mod {m}')
    return x % m

print(mod_inverse(3, 7))   # 5 (since 3*5=15≡1 mod 7)
print(mod_inverse(17, 26)) # 3 (since 17*3=51≡25... wait)
print(3 * mod_inverse(3, 7) % 7)  # 1 ✓
▶ Output
GCD=5, x=1, y=-2
Verify: 35*1 + 15*-2 = 5
5
3
1

LCM for Multiple Numbers

LCM of multiple numbers via pairwise LCM. Used for scheduling (when do cycles align?) and fraction arithmetic.

lcm_multiple.py · PYTHON
123456789101112
from math import gcd
from functools import reduce

def lcm_multiple(*nums) -> int:
    return reduce(lambda a, b: a * b // gcd(a, b), nums)

print(lcm_multiple(4, 6, 10))    # 60
print(lcm_multiple(3, 4, 5, 6))  # 60

# When do three periodic events align?
# Event A: every 4 days, B: every 6 days, C: every 10 days
print(f'All align on day: {lcm_multiple(4, 6, 10)}')  # 60
▶ Output
60
60
All align on day: 60

Applications

GCD and extended GCD appear throughout computer science:

RSA cryptography: Extended GCD computes the private key d = e⁻¹ mod φ(n). Fraction simplification: a/b in lowest terms = (a/gcd)/(b/gcd). Chinese Remainder Theorem: Extended GCD computes the modular inverses needed. Scheduling: LCM gives when periodic tasks next align. Competitive programming: GCD appears in almost every number theory problem.

🎯 Key Takeaways

  • GCD(a,b) = GCD(b, a mod b) — reduces to GCD(a,0)=a in O(log min(a,b)) steps.
  • LCM(a,b) = a*b / GCD(a,b) — always compute via GCD to avoid large intermediate values.
  • Extended GCD finds Bézout coefficients x,y such that ax + by = GCD(a,b).
  • Modular inverse of a mod m exists iff GCD(a,m) = 1 — compute via extended GCD.
  • Fibonacci pairs are worst case for Euclidean algorithm — Lamé's theorem bounds at 5×digits steps.

Interview Questions on This Topic

  • QWhat is the time complexity of the Euclidean algorithm and why?
  • QHow does the extended Euclidean algorithm compute modular inverses?
  • QWhen does the modular inverse of a (mod m) not exist?
  • QHow would you compute LCM of an array of numbers without overflow?

Frequently Asked Questions

Why use a*b//gcd instead of a//gcd*b for LCM?

a//gcdb computes the division first, reducing intermediate size and avoiding integer overflow. Always divide before multiplying: lcm = (a // gcd(a,b)) b.

What is Bézout's identity?

For any integers a and b, there exist integers x and y such that ax + by = GCD(a,b). The extended Euclidean algorithm finds these coefficients. This identity is the theoretical foundation for modular inverses and the Chinese Remainder Theorem.

🔥
Naren Founder & Author

Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.

← PreviousSieve of Eratosthenes — Prime Number GenerationNext →Prime Factorization and Divisors
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged