33.Search in Rotated Sorted Array
给定一个已排好序的数组,将数组循环移动后,给定一个目标整数,求目标整数是否在数组中,若在,返回下标,否则,返回 -1 ,必须使用 O(logn)时间复杂度。
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
思路:
题目要求O(logn)的时间复杂度,所以必须使用二分查找。因为数组被循环移动了,所以数组相当于分为2部分,设1部分为,里面元素都比较大的,2部分为整体元素都小的,每一部分内部都是升序排列的。题目难度在于,找到 mid所处于哪一部分,因此,在使用二分查找的时候,先确定mid在哪一部分,然后再使用二分查找即可。
int search(vector<int>& nums, int target) { int l = 0, r = nums.size() - 1, mid = 0; while (l <= r) { mid = (l + r) / 2; if (nums[mid] == target) return mid; else if (nums[mid] >= nums[l]) {//mid处于 1 部分 if (nums[mid] > target && nums[l] <= target) r = mid - 1; else l = mid + 1; } else {//mid处于2部分 if (nums[mid] < target && nums[r] >= target) l = mid + 1; else r = mid - 1; } } return -1; }
Java 版:
注意的点:要先区分哪一边有序,再确定 nums[ mid ] 与 target 的大小;而不是:先确定 nums[ mid ] 与 target 的大小,再确定哪一边有序。
class Solution { public int search(int[] nums, int target) { int l = 0, r = nums.length - 1, mid = 0; while(l <= r){ mid = (l + r) / 2 ; if(nums[mid] == target) return mid; if(nums[l] <= nums[mid]){ // 左边有序 if(nums[mid] > target && nums[l] <= target) r = mid - 1; // 只对确定有序的一边进行确定性的判断 else l = mid + 1; // 其余的都归为 else 类 }else{ //右边有序 if(target > nums[mid] && target <= nums[r]) l = mid + 1; else r = mid - 1; } } return -1; } }