반응형
Upper/Lower Bound란
Lower/Upper Bound는 이분 탐색에서 나온 개념으로 이분 탐색은 분할 정복을 이용하여 원하는 값을 적은 시간복잡도로 구할 수 있는 유용한 알고리즘이다.(분할정복 모르시는 분은 아래 링크 참고!!)
[알고리즘] 분할정복 (feat. Java)
분할정복 알고리즘이란 분할정복 알고리즘은 그대로 해결할 수 없는 큰 문제를 작은 문제로 분할하여 작은 문제부터 정복하여 결국에는 큰 문제를 해결하는 알고리즘이다. 대표적인 분할정복
codingralro.tistory.com
Upper/Lower Bound란, 중복을 허용하는 값들의 리스트(정렬된)에서 원하는 값 중 제일 첫번째 나오는 위치를 찾는 것은 Lower Bound, 원하는 값을 처음으로 초과하는 위치를 찾는 것을 Upper Bound라고 한다.
Lower Bound 예제 및 간략 코드
정렬된 배열 { 2, 2, 3, 4, 4, 6, 7 } 이 있고 값 3을 찾는다고 하자. 이 때에 값 2이 중복될 경우, 제일 처음 오는 값의 위치를 찾아야 한다면, 아래와 같은 과정을 거친다.
- start = 1, end = 7 ( 배열의 첫번째 인덱스를 편의상 1이라고 지정, 실제론 0부터 시작)
- mid = (1 + 7) / 2 = 4 번째 값을 2와 비교
- 4번째 값이 4는 2보다 큼
- 일반적인 이분탐색에서는 mid값이 원하는 값보다 큰 경우를 다루지만, lower bound에서는 크거나 같은 경우를 다룬다. 이 때에 크거나 같은 경우 end = mid - 1이 아닌 end = mid로 지정해줌
- start = 1, end = 4
- mid = (1 + 4 ) / 2 = 2 번째 값을 2와 비교
- mid의 값이 2가 2보다 같거나 크므로 end = mid로 지정
- start = 1, end = 2
- mid = (1 + 2) / 2 = 1 번째 값을 2와 비교
- mid의 값이 2가 2보다 같거나 크므로 end = mid로 지정
- start = 1, end = 1로 같아지므로 while문 종료
- 위지는 즉, start or end이다.
일반적인 이분탐색과의 차이점은 코드를 통해 자세히 알아보겠다.
int[] arr = {2, 2, 3, 4, 4, 6, 7};
int key = 2;
public int lowerBound(int[] arr, int key){
int start = 0;
int end = arr.length - 1;
//end == start면 그 값이 lower bound이므로 종료
while(start < end ) { //일반탐색 : start <= end
int mid = (start + end) / 2;
//일반적인 이분탐색의 경우 mid의 값이 찾는 값이면 mid를 리턴
/*
if(arr[mid] == key) {
return mid;
}
*/
if(arr[mid] >= key)
end = mid;
else
start = mid + 1;
}
return start;
}
Upper Bound
Upper Bound는 lower bound의 코드를 살짝만 수정하여 주면 된다. 초과하는 첫번째 값을 찾아주는 것이기 때문에 mid값이 원하는 값보다 작거나 같을 경우, start를 mid + 1로 초기화하는 것이다. (해당 값을 초과하는 처음 값을 찾는 것이기 때문에 mid값이 같은 경우에도 mid + 1을 해줌)
int[] arr = {2, 2, 3, 4, 4, 6, 7};
int key = 2;
public int lowerBound(int[] arr, int key){
int start = 0;
int end = arr.length - 1;
//end == start면 그 값이 upper bound이므로 종료
while(start < end ) {
int mid = (start + end) / 2;
if(arr[mid] > key)
end = mid;
else
start = mid + 1;
}
return start;
}
반응형
'기타 > 알고리즘' 카테고리의 다른 글
[알고리즘] 크루스칼(Kruskal) 알고리즘(feat. Java) (0) | 2023.10.11 |
---|---|
[알고리즘] 슬라이딩 윈도우 알고리즘(feat. Java) (1) | 2023.10.11 |
[알고리즘] 탐욕(그리디) 알고리즘 (0) | 2023.09.26 |
[알고리즘] 분할정복 (feat. Java) (0) | 2023.09.24 |
[알고리즘]세그먼트 트리(feat. Java) (0) | 2023.09.24 |