도입
분할 정복은 가장 유명한 알고리즘이다.
쉽게 생각해 "각개 격파"로 생각하면 된다.
분할 정복은 일반적인 재귀 호출과 다르게 문제를 같은 크기의 여러 조각을 만든다.
이런 분할 정복을 사용하는 알고리즘들은 세 가지 구성 요소를 책에서 소개하고 있다.
1. 문제를 더 작은 문제로 분할하는 과정 (divide)
2. 각 문제에 대해 구한 답을 원래 문제에 대한 답으로 병합하는 과정 (merge)
3. 더 이상 답을 분할하지 않고 곧장 풀 수 있는 매우 작은 문제 (base case)
분할 정복을 이용하면 같은 작업을 더 빠르게 처리할 수 있다.
예제 : 수열의 합
- 일반적인 재귀 호출을 이용한 코드
int recursiveSum(int n)
{
if (n == 1) return 1;
return n + recursiveSum(n - 1);
}
- 분할 정복을 이용한 코드
int fastSum(int n)
{
if (n == 1) return 1;
if (n % 2 == 1) return n + fastSum(n - 1);
return 2 * fastSum(n / 2) + pow(n / 2, 2);
}
위 분할 정복 코드를 부연 설명하자면,
fastSum(n) = 1 + 2 + . . . + n
= (1 + 2 + . . . + n/2) + ( (n/2 +1) + . . . + (n/2 + n/2) )
= (n/2) * (n/2) + 2 * (1 + 2+ . . . + 2/n)
= (n/2)^2 + 2 * fastSum(n/2) <단, n은 짝수> 이다.
시간 복잡도 분석
일반적인 재귀 호출을 이용한 경우 n번 함수 호출하는 것을 알 수 있다.
반면에 분할 정복을 이용하면 대락 n/2번 호출하는 것을 알 수 있다.
'알고리즘 > 알고리즘 문제 해결 전략' 카테고리의 다른 글
분할 정복 - 1. 쿼드 트리 뒤집기 (0) | 2020.11.16 |
---|---|
분할 정복 - 카라츠바 알고리즘 (1) | 2020.11.14 |
무식하게 풀기(Brute force) - 4. 시계 맞추기 (0) | 2020.11.13 |
무식하게 풀기(Brute force) - 3. 게임판 덮기 (0) | 2020.11.09 |
무식하게 풀기(Brute force) - 2. 소풍 (0) | 2020.11.08 |