|
| 1 | +# 지수적 탐색 |
| 2 | + |
| 3 | +#### 먼저 알아야 할 내용 |
| 4 | + |
| 5 | +- 이분 탐색 |
| 6 | + |
| 7 | +#### 문제 |
| 8 | + |
| 9 | +원소 n개로 이루어진 정렬된 배열이 주어졌을 때, 입력받은 원소의 인덱스를 반환하는 함수를 작성하라. |
| 10 | + |
| 11 | +#### 접근 방식 |
| 12 | + |
| 13 | +- 먼저, 찾는 원소가 존재하는 **범위**를 구한다. 이때, 범위는 *인덱스*를 2씩 계속 곱한 것을 사용한다. |
| 14 | +- 만약 그 범위가 유효하면(주어진 배열 안이라면) 그 범위에서 이분 탐색을 수행하여 결과를 반환한다. |
| 15 | +- 아니라면, -1을 반환한다. |
| 16 | + |
| 17 | +#### 예시 |
| 18 | + |
| 19 | +```markdown |
| 20 | +배열 = [1, 2, 3, 4, 5, 6, 7, ... 998, 999, 1_000] |
| 21 | + |
| 22 | +찾는 원소 = 998 |
| 23 | +인덱스 = 0 |
| 24 | +1. 범위 구하기 |
| 25 | +인덱스 = 1, 2, 4, 8, 16, 32, 64, ..., 512, ..., 1_024 |
| 26 | +인덱스 = 1일때 배열의 1번째 원소(1)가 찾는 원소(998)보다 작으므로 인덱스에 2를 곱한다. |
| 27 | +인덱스 = 2일때 배열의 2번째 원소(2)가 찾는 원소(998)보다 작으므로 인덱스에 2를 곱한다. |
| 28 | +... |
| 29 | +10번째 반복 이후 인덱스는 1_024가 되고, 이는 배열 밖에 있으므로 멈춘다. |
| 30 | +2. 이분 탐색 |
| 31 | +찾는 원소는 512번째와 1000번째 사이에 있으므로, 이 구간에서 이분 탐색을 이용한다. |
| 32 | +``` |
| 33 | + |
| 34 | +***참고***: 이분 탐색의 구간이 512에서 1_000인 것은 1.에서 얻은 인덱스 1_024가 배열의 마지막 인덱스 1_000보다 컸기 때문이다. |
| 35 | + |
| 36 | +#### 시간 복잡도 |
| 37 | + |
| 38 | +**최악의 경우:** `O(log *i*)` (여기서 `*i*`는 찾는 원소의 인덱스이다.) |
| 39 | + |
| 40 | +**최선의 경우:** `O(*1*)` |
| 41 | + |
| 42 | +#### 시간 복잡도에 대한 설명 |
| 43 | + |
| 44 | +- 알고리즘의 첫번째 부분을 수행하는 데에 필요한 시간 복잡도는 **O( log *i* )**이다. 이는 인덱스에 2를 `⌈log(i)⌉`번 곱하고 나면 찾는 원소의 인덱스보다 크거나 같기 때문이다. 식으로는 `2^⌈log(i)⌉ >= i`와 같이 나타낼 수 있다. |
| 45 | +- 알고리즘의 두번째 부분을 수행하는 데에 필요한 시간 복잡도 역시 **O( log *i* )**이다. 단순 이분 탐색의 시간 복잡도는 구간의 크기 *k*일때 O(log *k*)이다. 여기서 이분 탐색을 수행하는 구간은 `2^(i-1)`부터 `2^i`까지 이므로, 구간의 크기는 `2^i - 2^(i-1) = 2^(i-1`이다. |
| 46 | + |
| 47 | +따라서, 전체 알고리즘의 시간 복잡도는 다음과 같다. |
| 48 | + |
| 49 | +```mathematica |
| 50 | +O(log i) + O(log i) = 2*O(log i) = O(log i) |
| 51 | +``` |
| 52 | + |
| 53 | +#### 이분 탐색 vs 지수적 탐색 |
| 54 | + |
| 55 | +이분 탐색과 지수적 탐색을 실제 상황에서 비교해보자. 크기 `1_000_000`인 배열이 있고, 우리가 찾는 원소는 그 배열의 4번째에 있다고 하자. 이떄, |
| 56 | + |
| 57 | +- 이분 탐색을 이용하면 배열의 가운데에서 시작하여, 여러 번의 반복 이후에야 4번째 원소임을 찾을 수 있다. |
| 58 | +- 지수적 탐색은 단 2번의 반복만에 4번째 원소를 찾을 수 있다. |
| 59 | + |
| 60 | +#### 구현 |
| 61 | + |
| 62 | +- [C++](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/exponential_search.cpp) |
| 63 | +- [자바스크립트](https://github.com/TheAlgorithms/Javascript/blob/master/Search/ExponentialSearch.js) |
0 commit comments