노트

분할 정복

Divide and Conquer

CS#algorithm · 연결된 개념 7개

쉽게 말하면

분할 정복은 큰 문제를 같은 모양의 작은 문제로 반씩, 또 반씩 쪼갠 뒤 하나씩 풀고 답을 합치는 방식이에요. 답안지 1000장 정리도 두세 장짜리 더미까지 나누면 각각은 바로 끝나요.

비유가 깨지는 곳 이 방식은 나눈 조각들이 서로 겹치지 않을 때 잘 맞아요. 피보나치처럼 같은 부분 문제가 반복해서 나오면 결과를 저장해 재사용하는 동적 프로그래밍이 더 맞아요.

문제를 같은 모양의 더 작은 문제로 나누고(분할, Divide), 각각을 풀고(정복, Conquer), 그 결과를 합쳐(결합, Combine) 원래 문제를 푸는 방식. 대개 재귀로 표현하고, 나눌 때마다 크기가 절반으로 줄면 log n 단계 만에 바닥에 닿는다.

  • 이진 탐색: 가운데와 비교해 절반을 버린다. 결합 단계가 없는 가장 단순한 형태로 O(log n)
  • 병합 정렬: 반으로 나눠 각각 정렬한 뒤 합친다. O(n log n)
  • 퀵 정렬: 피벗 기준으로 나눈 뒤 각각 정렬한다. 결합이 필요 없다
  • 큰 수 곱셈, 가장 가까운 두 점 찾기, 행렬 곱셈 같은 고전 문제도 이 방식으로 빨라진다

동적 프로그래밍과의 차이

나눈 부분 문제들이 서로 겹치지 않으면 분할 정복, 같은 부분 문제가 반복해서 나오면 결과를 저장해 재사용하는 동적 프로그래밍이 맞다. 피보나치를 단순 재귀로 나누면 같은 계산을 수없이 반복하는 것이 그 예다.

다른 패턴은 알고리즘 문제 풀이 접근법, 복잡도 계산은 빅오 표기법.

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 정렬 알고리즘

    컬렉션의 원소를 어떤 순서(크기, 사전순, 날짜…)로 다시 배치하는 알고리즘. 같은 일을 하는 방법이 여럿이고 각자 강점이 달라, 트레이드오프를 익히기 좋은 주제다.

  • 섣부른 최적화

    "섣부른 최적화는 모든 악의 근원이다." 도널드 크누스(Donald Knuth)가 1974년 글 「Structured Programming with go to Statements」에서 쓴 말이다. 원문의 맥락은 작은 효율은 대부분(약 97%)의 경우 잊으라는 것이고, 정말 중요한 3%는 놓치지 말라는 말이 이어진다.

  • 반복문을 파이프라인으로 바꾸기

    for 반복문을 filter·map·reduce 같은 컬렉션 연산의 연쇄, 즉 컬렉션 파이프라인(Collection Pipeline)으로 바꾸는 리팩터링. 각 원소가 어떤 단계를 거치는지가 위에서 아래로 읽힌다.

  • 빈도수 세기 패턴

    값이 몇 번 나오는지를 객체나 Map에 모아 두고 비교하는 풀이 패턴. 배열이나 문자열끼리 비교할 때 생기기 쉬운 중첩 반복 O(n²)을 O(n)으로 줄인다.

  • 청킹과 코드 읽기

    여러 정보를 의미 있는 덩어리 하나로 묶어 기억하는 것. 아는 것이 많을수록 코드를 큰 덩어리로 읽는다.

보기 옵션