
알고리즘 복잡도(Algorithmic Complexity)는 문제를 해결하기 위해 알고리즘이 필요로 하는 컴퓨팅 자원을 수학적으로 표현한 것이다.
복잡도를 줄이는 것이 곧 효율적인 알고리즘을 만드는 핵심이다. 보통 Big O 표기법을 사용해 입력 크기(n)에 따른 성능 변화를 분석한다.
💡 시간과 공간은 종종 상충한다.
실행 속도를 높이려면 메모리를 더 쓰게 되고, 메모리를 절약하면 실행 속도가 느려질 수 있다.
이를 공간-시간 트레이드오프(Space-Time Tradeoff) 라고 한다.
복잡도 계산은 보통 최악의 경우(worst-case)를 기준으로 한다.
n의 함수로 표현 예시:
입력 크기와 관계없이 항상 일정한 시간에 수행된다.
def get_first_element(arr):
return arr[0] # 인덱스로 바로 접근 → O(1)
print(get_first_element([1, 2, 3]))
입력 크기를 매번 절반으로 줄이는 알고리즘.
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
print(binary_search([1, 3, 5, 7, 9], 7))
모든 원소를 한 번씩 확인한다.
def linear_search(arr, target):
for i, value in enumerate(arr):
if value == target:
return i
return -1
print(linear_search([1, 3, 5, 7, 9], 5))
효율적인 정렬 알고리즘에서 자주 등장.
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(left, right):
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result.extend(left[i:])
result.extend(right[j:])
return result
print(merge_sort([5, 2, 9, 1, 5, 6]))
중첩 반복문을 사용하는 경우.
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
print(bubble_sort([5, 2, 9, 1, 5, 6]))
입력 크기에 따라 실행 시간이 기하급수적으로 증가.
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(10))
모든 경우의 수를 완전 탐색.
import itertools
def traveling_salesman(cities):
shortest_path = None
shortest_distance = float('inf')
for path in itertools.permutations(cities):
distance = sum(abs(path[i] - path[i + 1]) for i in range(len(cities) - 1))
if distance < shortest_distance:
shortest_distance = distance
shortest_path = path
return shortest_path, shortest_distance
print(traveling_salesman([1, 2, 3]))
알고리즘 복잡도를 이해하면
이 가능해진다. 앞으로 알고리즘을 설계할 때는 단순히 “잘 동작하는 코드”가 아니라, 성능까지 고려한 코드를 목표로 해야 한다.