high = mid와 high = mid - 1의 차이
일반적인 이진 탐색에서는 low = mid + 1 또는 high = mid - 1을 사용합니다. 이는 정확한 값을 찾는 경우에 주로 쓰이며, 조건에 따라 탐색 범위를 한 칸씩 좁히는 방식입니다. 하지만, lower bound와 upper bound는 찾고자 하는 값이 첫 번째로 등장하는 위치 또는 값을 초과하는 첫 번째 위치를 찾는 것이 목적이므로, 다음과 같은 방식으로 처리해야 합니다.
lower bound와 upper bound에서는 high = mid 또는 low = mid가 사용되는 이유:
- lower bound: 배열에서 target 이상이 처음 등장하는 위치를 찾습니다.
- arr[mid] >= target인 경우, mid 위치가 목표 값 또는 그 이상의 값이 등장할 수 있는 위치일 수 있으므로 high = mid로 설정합니다. 즉, 현재 범위에서 이 이상을 찾으러 더 좁혀 나가는 것이죠.
- 만약 arr[mid] < target인 경우, 이는 우리가 찾는 값보다 작으므로, low = mid + 1로 설정해서 왼쪽은 배제하고 오른쪽만 탐색하게 됩니다.
- upper bound: 배열에서 target을 초과하는 첫 번째 위치를 찾습니다.
- arr[mid] > target인 경우, mid 위치는 우리가 찾는 값보다 큰 값이 있는 첫 번째 위치일 수 있으므로 high = mid로 설정합니다.
- 반면, arr[mid] <= target인 경우, low = mid + 1로 설정하여 현재 위치에서 계속 오른쪽을 탐색하게 됩니다.
이런 방식으로 high = mid로 설정하면, 범위가 점차 축소되면서 우리가 찾는 "최초로 등장하는 위치" 또는 "초과하는 첫 번째 위치"를 정확하게 찾아낼 수 있습니다.
>=와 >의 구분
- **lower bound**는 **>=**를 사용해서 찾는 값이 처음 등장하는 위치를 구합니다. 즉, 배열에서 찾는 값과 같거나 큰 값이 처음 등장하는 위치를 찾아내는 것이 목적입니다.
- **upper bound**는 **>**를 사용해서 찾는 값보다 큰 값이 처음 등장하는 위치를 구합니다.
두 값의 차이는 같은 값이 배열에서 몇 번 나왔는지를 계산하는 데 사용됩니다. 즉, upper bound - lower bound는 배열에서 해당 값이 몇 번 등장했는지를 계산하게 됩니다. 이 방식은 정렬된 배열에서 중복된 값의 개수를 세는 데 유용합니다.
예시로 이해해보자
만약 배열 arr = [1, 2, 2, 2, 3, 4]에서 target = 2일 때:
- lower bound는 2 이상이 처음 나오는 위치이므로 arr[1]이 됩니다.
- upper bound는 2보다 큰 값이 처음 나오는 위치이므로 arr[4]이 됩니다.
이 경우, upper bound - lower bound = 4 - 1 = 3이 되며, 배열에서 값 2가 3번 등장한 것을 알 수 있습니다.
따라서, upper - lower를 통해 배열에서 특정 값의 등장 횟수를 정확히 셀 수 있는 것이죠.
요약
- **high = mid**는 lower/upper bound에서 사용되어, 값을 초과하거나 최소 값을 찾기 위해 범위를 좁히는 방식입니다.
- **>=와 >**를 구분하는 이유는 lower bound와 upper bound를 정확히 계산하기 위해서이며, 이 차이를 통해 특정 값의 등장 횟수를 구할 수 있습니다.
'알고리즘' 카테고리의 다른 글
| [BOJ. 2983] 개구리 공주 (2) | 2025.04.13 |
|---|---|
| [알고리즘] 시뮬레이션에서 자주 나오는 것들 정리 (0) | 2024.09.25 |
| [알고리즘, Java] 꽤나 사용하는 Java 메서드 알아보기 (0) | 2024.09.01 |
| 알고리즘에서 많이 쓰는 방식 (0) | 2024.08.25 |
| [Programmers | JAVA] 광고 삽입 - 슬라이딩 윈도우 (0) | 2024.06.05 |