题目描述
- 值互不相同:不用考虑重复值情况(要不然比较麻烦)
思路 & 代码
- 重点在于保证O(logn)的时间复杂度
- 看成两个数组:前半段 & 后半段。根据两个数组的极值来判断 target 在哪个数组,再进行判断即可。
- 先一次二分,找到前半段、后半段的分界下标。
- 再一次二分,找到在某半段中的 target
- 注意:要考虑极端情况:在下标0处旋转,相当于没有旋转。
class Solution {public int search(int[] nums, int target) {int k = -1, low = 0, top = nums.length - 1;while(low <= top){k = (low + top) / 2;if(k + 1 == nums.length || nums[k] > nums[k + 1]){break;}if(nums[k] < nums[0]){top = k - 1;}else{low = k + 1;} }if(target > nums[nums.length-1] || k == nums.length-1){return binary(nums,0,k,target);}else{return binary(nums,k+1,nums.length-1,target);}}public int binary(int[] nums,int left,int right,int target){if(left >= right){if(target == nums[left]){return left;}return -1;}int half = (left+right)/2;if(target == nums[half]){return half;}else if(target > nums[half]){return binary(nums,half+1,right,target);}else{return binary(nums,left,half-1,target);}}
}
更新版
class Solution {public int search(int[] nums, int target) {int k = -1;int left = 0, right = nums.length - 1;while(left <= right) {k = (left + right) / 2;if(k + 1 == nums.length || nums[k] > nums[k + 1]) {break;}if(nums[k] < nums[0]) {right = k - 1;}else {left = k + 1;}}if(target > nums[nums.length - 1] || k == nums.length - 1) {return binary(nums, 0, k, target);}else {return binary(nums, k + 1, nums.length - 1, target);}}public int binary(int[] nums, int left, int right, int target) {if(left > right) {return -1;}int mid = (left + right) / 2;if(target == nums[mid]) {return mid;}else if(nums[mid] > target) {return binary(nums, left, mid - 1, target);}else {return binary(nums, mid + 1, right, target);}}
}