제목 : LeetCode (33)
오름차순으로 정렬 된 배열이 미리 알려지지 않은 특정 지점에서 회전한다고 가정합니다.
(예를 들어 배열 [0,1,2,4,5,6,7]은 [4,5,6,7,0,1,2]가 될 수 있습니다).
지정된 대상 값을 검색하고 대상 값이 배열에 있으면 해당 인덱스를 반환하고 그렇지 않으면 -1을 반환합니다.
배열에 중복 요소가 없다고 가정 할 수 있습니다.
알고리즘의 시간 복잡도는 O (log n) 수준이어야합니다.
예 1 :
입력 : nums = [4,5,6,7,0,1,2], target = 0
출력 : 4
예 2 :
입력 : nums = [4,5,6,7,0,1,2 ], target = 3
출력 : -1
문제 해결책 : 문제
의 의미는 회전하는 배열에서 주어진 값을 검색하도록하는 것입니다. 존재하는 경우이 값의 해당 좌표를 반환하고, 존재하지 않는 경우 -1을 직접 반환합니다. 신중하게 생각하면 실제로 이진 검색의 변형이라는 것을 알게 될 것입니다. 이진 검색을 고려하십시오. 그러나이 질문의 어려움은 원래 배열이 회전 된 위치를 모른다는 것입니다. 분석 할 제목 배열 [0 1 2 4 5 6 7]에는 다음과 같은 7 가지 회전 방법이 있습니다.
[0 1 2 4 5 6 7]
[7 0 1 2 4 5 6]
[6 7 0 1 2 4 5]
[5 6 7 0 1 2 4]
[4 5 6 7 0 1 2]
[2 4 5 6 7 0 1]
[1 2 4 5 6 7 0]
관찰 결과 : 중앙값이 맨 오른쪽 값보다 크면 왼쪽이 순서대로, 중앙값이 맨 오른쪽 값보다 작 으면 오른쪽이 순서대로 표시됩니다. 따라서 목표 값이이 영역에 있는지 확인하기 위해 순서가 지정된 절반의 처음과 마지막 두 배열 만 사용하면됩니다. 그러면 유지할 절반을 결정할 수 있습니다.
int rotatedBinarySearch(int[] arr, int target){
// 最左侧元素下标
int left = 0;
// 最右侧元素下标
int right = arr.length - 1;
while(left <= right){
// 中间元素下标
int mid = left + (right - left) / 2;
if(arr[mid] == target){
return mid;
}
// 情况1:如果中间元素在旋转点左侧
if(arr[mid] >= arr[left]){
//target 如果位于中间元素的左侧
if(arr[mid] > target && target >= arr[left]){
right = mid - 1;
}else{
left = mid + 1;
}
}
// 情况2:中间元素在旋转点的右侧
else{
// target 如果位于中间元素的右侧
if(arr[mid] < target && target <= arr[right]){
left = mid + 1;
}else{
right = mid - 1;
}
}
}
return -1;
}