法一(二分查找)
/**
* (1)将数组从中间一分为二,得到一个升序数组和一个非升序数组
* (2)要找的值必在 “一个升序数组” 里,但并不意味着这个值就在一开始二分到的升序数组里
* (3)如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的
* (4)在升序数组中,判断目标值是否大于等于最左值,小于等于最右值
* 是,则目标值就在这个升序数组里,继续二分
* 否,则目标值在非升序数组里,继续二分
* @param nums
* @param target
* @return
*/
public int search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < nums[right]) { // [mid, right]是有序数组
if (target >= nums[mid] && target <= nums[right]) {
left = mid + 1;
} else {
right = mid - 1;
}
} else { // [left, mid]是有序数组
if (target >= nums[left] && target <= nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
}
}
return -1;
}
本地测试
/**
* 33. 搜索旋转排序数组
*/
lay.showTitle(33);
Solution33 sol33 = new Solution33();
int[] nums33 = new int[]{4,5,6,7,0,1,2};
int target33 = 0;
System.out.println(sol33.search(nums33, target33));