math
CHAPTER 26 / 45
읽기 약 2분
FUNCTION
빅오 표기법: 코드 속도의 수학
핵심 개념
O(1)·O(log n)·O(n)·O(n log n)·O(n²)·O(2^n) — 데이터 1만→100만일 때 차이를 코드로 증명.
본문
Big-O = 입력 크기 N에 따른 성장률
O(1) 상수
O(log n) 로그 (이진 탐색)
O(n) 선형 (단순 루프)
O(n log n) 머지/퀵 정렬
O(n²) 이중 루프
O(n³) 삼중 루프
O(2^n) 재귀 피보나치 (메모 X)
O(n!) 순열 모두 시도시각적 비교
import math
import matplotlib.pyplot as plt
import numpy as np
n = np.linspace(1, 30, 100)
plt.figure(figsize=(10, 6))
plt.plot(n, np.ones_like(n), label='O(1)')
plt.plot(n[1:], np.log2(n[1:]), label='O(log n)')
plt.plot(n, n, label='O(n)')
plt.plot(n[1:], n[1:] * np.log2(n[1:]), label='O(n log n)')
plt.plot(n, n ** 2, label='O(n²)')
plt.plot(n, 2 ** n, label='O(2^n)')
plt.ylim(0, 1000)
plt.xlabel('N (입력 크기)')
plt.ylabel('연산 횟수')
plt.legend()
plt.grid(True)
plt.title('Big-O 성장률 비교')
plt.show()
# O(2^n)이 가장 빠르게 폭발데이터 크기별 시간 추정
# 1초에 1억 연산 가능 가정
def estimate_time(complexity, n):
operations = {
'O(1)': lambda x: 1,
'O(log n)': lambda x: math.log2(x) if x > 0 else 0,
'O(n)': lambda x: x,
'O(n log n)': lambda x: x * math.log2(x) if x > 0 else 0,
'O(n²)': lambda x: x * x,
'O(2^n)': lambda x: 2 ** min(x, 60), # 큰 수 방지
}[complexity](n)
seconds = operations / 100_000_000
if seconds < 1: return f"{seconds*1000:.2f}ms"
if seconds < 60: return f"{seconds:.1f}초"
if seconds < 3600: return f"{seconds/60:.1f}분"
if seconds < 86400: return f"{seconds/3600:.1f}시간"
return f"{seconds/86400:.0f}일"
print(f"{'N':>10} {'O(n)':>10} {'O(n log n)':>15} {'O(n²)':>15} {'O(2^n)':>15}")
for n in [10, 100, 1_000, 10_000, 100_000, 1_000_000]:
print(f"{n:>10,} {estimate_time('O(n)', n):>10} "
f"{estimate_time('O(n log n)', n):>15} "
f"{estimate_time('O(n²)', n):>15} "
f"{estimate_time('O(2^n)', min(n, 30)):>15}")
# 결과:
# N=100,000일 때 O(n²) = 100억 = 100초+
# N=30일 때 O(2^n) = 10초+코드별 Big-O 측정
import time
def measure(fn, *args):
t0 = time.perf_counter()
fn(*args)
return time.perf_counter() - t0
# O(n) — 단일 루프
def linear(arr):
return sum(arr)
# O(n²) — 중첩 루프
def quadratic(arr):
pairs = []
for i in arr:
for j in arr:
pairs.append((i, j))
return pairs
# O(n log n) — 정렬
def n_log_n(arr):
return sorted(arr)
# 데이터 크기별 시간 비교
for size in [100, 1000, 10_000]:
arr = list(range(size))
t1 = measure(linear, arr)
t2 = measure(quadratic, arr)
t3 = measure(n_log_n, arr)
print(f"N={size:>6} | O(n): {t1*1000:.3f}ms | O(n²): {t2*1000:.3f}ms | O(n log n): {t3*1000:.3f}ms")Big-O 분석 — 실전 패턴
# 패턴 1: 단일 루프 → O(n)
def find_max(arr):
m = arr[0]
for x in arr[1:]:
if x > m:
m = x
return m
# 패턴 2: 중첩 루프 → O(n²)
def has_duplicates_v1(arr):
for i, a in enumerate(arr):
for j, b in enumerate(arr):
if i != j and a == b:
return True
return False
# 패턴 2 개선: O(n) — 해시셋
def has_duplicates_v2(arr):
seen = set()
for x in arr:
if x in seen:
return True
seen.add(x)
return False
# 패턴 3: 절반씩 줄이기 → O(log n)
def binary_search(arr, target):
lo, hi = 0, len(arr) - 1
while lo <= hi:
mid = (lo + hi) // 2
if arr[mid] == target: return mid
if arr[mid] < target: lo = mid + 1
else: hi = mid - 1
return -1
# 패턴 4: 분할 정복 → O(n log n)
def merge_sort(arr):
if len(arr) <= 1: return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(a, b):
result = []
i, j = 0, 0
while i < len(a) and j < len(b):
if a[i] < b[j]:
result.append(a[i]); i += 1
else:
result.append(b[j]); j += 1
return result + a[i:] + b[j:]최악 vs 평균 vs 최선
빠른정렬 (Quicksort):
- 최선: O(n log n) — 균등 분할
- 평균: O(n log n)
- 최악: O(n²) — 이미 정렬된 입력
해시 검색:
- 평균: O(1)
- 최악: O(n) — 모든 키가 한 버킷
→ Big-O는 보통 최악을 의미. 실전은 평균도 봐야 함.다음 챕터
CH.27 "공간 복잡도" — 시간만 빠르면 끝이 아니라 메모리도 중요.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 알고리즘 코드 10개의 Big-O를 분석해서 가장 느린 것 Top 3와 N별 예상 시간을 보고해줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
한국 코딩 테스트에서 시간초과로 떨어지는 사례 Top 10과 각각의 복잡도 개선 패턴을 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 코드베이스의 모든 함수에서 중첩 루프 + 리스트 in 검사 위치를 자동 분석해서 우선 개선안을 만들어줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 시니어 면접에서 Big-O 질문 출제 빈도와 깊이를 한국 IT 대기업 기준으로 솔직히 알려줘.
⭐ 이것만 기억하세요
빅오 표기법: 코드 속도의 수학은 이 3가지만 확실히 잡으세요
1.Big-O는 입력 크기 N에 따른 성장률 — 상수 무시, 최고차항만 보존 (O(2n+5) → O(n))
2.O(n²) 알고리즘은 N=10만에서 100초+ 걸림 — 데이터 1만 넘으면 O(n log n) 이하 필수
3.다음 챕터 CH.27에서 공간 복잡도 — 시간뿐 아니라 메모리 사용도 분석
공유하기
진행도 26 / 45