반응형
분할 정복의 첫 번째 예제이다.
책 앞에 분할 정복에 대한 설명은 자세히 설명되어 있으므로 생략하겠다.
첫 번째 예제인 수열의 빠른 합과 행렬의 빠른 제곱을 구하는 문제인데 우리는 이 문제를 분할 정복으로 풀기 위해서 1+2+.... N까지의 합을 반으로 쪼갤 것이다. 그러면
이렇게 보기 좋은 식이 나온다.
그런데 우리는 분할정복을 해야 하니까 기저 사례로 가서 1로 만나면 분할이 완료가 되었다고 코딩을 해야 하는데 저렇게 되어버리면 ((n/2)+1).....+ N) 부분이 a부터 b까지의 합 형식으로 표현이 되어 있어서 분할 정복으로 사용하기 불편하므로 식을 바꿔주어야 한다.
위에 나온 식을 첫 번째 사진 fastSum(x) 형식으로 바꾸어 주면?
이렇게 식이 정리되고 밑에 사진처럼 정의할 수 있다.
1 2 3 4 5 6 7 8 |
int fastSum(int n){ //기저사례 if (n == 1) return 1; if (n % 2 == 1) return fastSum(n - 1) + n; //홀수일경우 return 2 * fastSum(n / 2) + (n / 2) * (n / 2); //짝수일경우 } Colored by Color Scripter |
cs |
위 식은 짝수를 기준으로 분할 정복을 설립한 거라 홀수일 경우에는 -1을 해준 다음에 마지막에 빼준값을 더 해준다.
위의 재귀 함수 식이 어떻게 흘러가는지 확인해 보면 이렇다
사진을 보면 재귀 호출을 할 때 n의 이진수 자리의 표현이 1이면 0으로 바뀌고 0이면 끝자리가 없어진다는 것을 알 수 있다. 따라서 이 함수의 알고리즘 복잡도는 이진수 표현의 자릿수 첫자리를 제외하고 나타나는 1의 개수가 되고 두 값의 상한은 모두 logn이므로 이 알고리즘의 실행 시간은 O(logn)이다.
반응형
'Algorithm' 카테고리의 다른 글
[#2-4]분할정복-문제: 울타리 잘라내기(문제 ID: FENCE) (0) | 2021.09.05 |
---|---|
[#2-3]분할정복-문제: 쿼드 트리 뒤집기(문제 ID: QUADTREE) (0) | 2021.09.05 |
[#2-2]분할정복-예제: 카라츠바의 빠른 곱셈 알고리즘 (0) | 2021.09.05 |
[#1]완전탐색-n개의 원소 중 m개를 고르는 모든 조합을 찾는 알고리즘 (0) | 2021.09.05 |
이분탐색 구현 팁 및 반환값 줄이기(부제: 공부하며 정리하는 생각들) (0) | 2021.08.09 |