文章目录
- 题目描述
- 思路 & 代码
题目描述
- 有序数组中搜索值,显然用二分
- 旋转带来的影响并不大,只要多加几个判断,改改范围就行。
思路 & 代码
- 首先找出两部分升序子数组的分割点k
- 然后再判断需要在哪个子数组进行二分,并进行二分即可。
- 注意二分时候一定要舍去已判断无效值(也就是half)
更新。。之前的方法实际上不满足O(logn),分割点查找应该也使用二分查找。
class Solution {public int search(int[] nums, int target) {// 思路:一次分割点查找O(logn)。两次二分查找O(logn)int k = -1, low = 0, top = nums.length - 1;while(low <= top){k = (low + top) / 2;// 找到的情况:注意长度为1时,需要进行k + 1 == nums.length判断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){// l = 0,r = -1的情况也要考虑if(left >= right){if(target == nums[left]){return left;}return -1;}int half = (left+right)/2;// 相等判断if(target == nums[half]){return half;}// 缩短范围,+-1去掉已判断的halfelse if(target > nums[half]){return binary(nums,half+1,right,target);}else{return binary(nums,left,half-1,target);}}
}