33. 회전 정렬 배열 검색 - 이진 검색
정수 배열 nums는 오름차순으로 배열되어 있으며 배열의 값이 서로 다릅니다.
함수에 전달되기 전에 nums는 이전에 알려지지 않은 인덱스 k(0 <= k < nums.length)에서 회전하여 배열이 [nums[k], nums[k+1], …, nums[n]이 됩니다. -1], nums[0], nums[1], …, nums[k-1]] (아래 첨자는 0부터 계산되기 시작합니다). 예를 들어, [0,1,2,4,5,6,7]은 인덱스 3에서 회전한 후 [4,5,6,7,0,1,2]가 될 수 있습니다.
회전된 배열 nums와 정수 타겟을 제공합니다. 타겟 값 target이 nums에 존재하면 해당 첨자를 반환하고, 그렇지 않으면 -1을 반환합니다.
이 문제를 해결하려면 O(log n)의 시간 복잡도를 갖는 알고리즘을 설계해야 합니다.
예시 1:
입력: 숫자 = [4,5,6,7,0,1,2], 대상 = 0
출력: 4
예시 2:
입력: 숫자 = [4,5,6,7,0,1,2], 대상 = 3
출력: -1
예시 3:
입력: nums = [1], 대상 = 0
출력: -1
이 질문은 사실 별로 간단하지 않습니다. Tong Xu가 볼 때 일회성 순회를 사용하여 문제를 해결할 수 있다는 것을 이해하지만, 질문에는 log(n) 수준의 실행 속도를 사용하여 해결해야 한다는 것이 명확하게 명시되어 있습니다. the blogger 아이디어는 먼저 이진 검색을 사용하여 회전 위치를 찾은 다음 두 번의 이진 검색을 사용하여 목표 값을 찾는 것입니다.
솔루션 코드는 다음과 같습니다.
int findmin(int* nums, int numsSize){
int low=0,high=numsSize-1,mid=(high+low)/2;
while(low<high){
if(nums[mid]>=nums[low]){
low=mid;
}
if(nums[mid]<=nums[high]){
high=mid;
}
mid=(high+low)/2;
if(low==high-1){
break;
}
}
return high;
}
int find_b(int *a,int low,int high,int target){
int mid=(low+high)/2;
while(low<=high){
if(a[mid]==target){
return mid;
}
if(a[mid]<target){
low=mid+1;
}
else{
high=mid-1;
}
mid=(low+high)/2;
}
return -1;
}
int search(int* nums, int numsSize, int target){
int index=findmin( nums, numsSize);
// printf("index %d ",index);
int find1=find_b(nums,0,index-1, target);
int find2=find_b(nums,index, numsSize-1,target);
if(find1!=-1){
return find1;
}
if(find2!=-1){
return find2;
}
return -1;
}