题目:
给你一个升序排列的整数数组 nums ,和一个整数 target 。
假设按照升序排序的数组在预先未知的某个点上进行了旋转。(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
示例 1:输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4
示例 2:输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1
示例 3:输入:nums = [1], target = 0
输出:-1
提示:1 <= nums.length <= 5000
-10^4 <= nums[i] <= 10^4
nums 中的每个值都 独一无二
nums 肯定会在某个点上旋转
-10^4 <= target <= 10^4
解题分析:
时间复杂度要求logn,所以采用二分法;
首先要知道,我们随便选择一个点,将数组分为前后两部分,其中一部分一定是有序的。
具体步骤:
我们可以先找出mid,然后根据mid来判断,mid是在有序的部分还是无序的部分
假如mid小于start,则mid一定在右边有序部分。 假如mid大于等于start, 则mid一定在左边有序部分。
然后我们继续判断target在哪一部分, 我们就可以舍弃另一部分了
我们只需要比较target和有序部分的边界关系就行了。 比如mid在右侧有序部分,即[mid, end] 那么我们只需要判断 target >= mid && target <= end 就能知道target在右侧有序部分,我们就 可以舍弃左边部分了(start = mid + 1), 反之亦然。
public class Solution {
public int search(int[] nums, int target) {
int right = 0;
int left = nums.length - 1;
while (right <= left){
int mid = (right + left ) / 2;
if(nums[mid] == target){
return mid;
}
if (nums[mid] >= nums[right]){
if(target >= nums[right] && target < nums[mid]){
left = mid - 1;
}else{
right = mid + 1;
}
}else{ // nums[mid] < nums[right]
if(target > nums[mid] && target <= nums[left]){
right = mid + 1;
}else{
left = mid - 1;
}
}
}
return -1;
}
}
时间复杂度:$O(logN)$
空间复杂度:$O(1)$