package com.david.leetcode;
public class T33 {
class Solution {
/**
普通的二分查找
*/
private int binarySearch(int[] nums,int start,int end,int target){
if(start<=end){
int mid = (start+end)/2;
if(nums[mid]==target) return mid;
else if(nums[mid]<target){
return binarySearch(nums,mid+1,end,target);
}else{
return binarySearch(nums,start,mid-1,target);
}
}
return -1;
}
/**
查找旋转点(也就是最小值的坐标),找旋转点的原因见下面search()处
*/
private int searchRotation(int[] nums,int start,int end){
if(nums[start]<nums[end]) return start;
int mid = (start+end)/2;
if(nums[mid]<nums[mid+1]){
//注意这里时跟start索引比而不是跟mid-1比,只有这样才能:说明从start-mid是一个递增序列,所以最小值只可能右半个区间
if(nums[mid]>nums[start]){
return searchRotation(nums,mid+1,end);
}else{
//注意这里mid要取得到,因为当前nums[mid]有可能是最小值
return searchRotation(nums,start,mid);
}
//nums[mid]>nums[mid+1],则意味着mid+1即为旋转点
}else{
return mid+1;
}
}
/**
根据target与最小值以及nums[n-1]处值的大小关系,去对应区间来检索target
*/
public int search(int[] nums, int target) {
int n = nums.length;
if(n==0) return -1;
if(n==1) return (nums[0]==target)?0:-1;
int minIdx = searchRotation(nums,0,n-1);
if(nums[minIdx]==target) return minIdx;
if(minIdx==0) return binarySearch(nums,0,n-1,target);
//如果nums[minIdx]<target<nums[n-1]:则从右半个区间去找
else if(target<=nums[n-1]) return binarySearch(nums,minIdx+1,n-1,target);
else{
//如果target>nums[n-1]则从左半个区间去找
return binarySearch(nums,0,minIdx-1,target);
}
}
}
}
leetcode T33
最新推荐文章于 2024-07-12 21:04:18 发布