假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7]
可能变为 [4,5,6,7,0,1,2]
)。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法:
有题目可知,数组是分为两部分递增的的,并且前半部分的min大于后半部分的max。
如果nums[0] <= target
说明target之能出现在nums[0]和旋转点之间的前半部分有序序列。将0向后遍历,如果nums[i]==target
返回i,如果出现元素大于nums[0],说明进入后半部分有序序列,说明找不到直接返回-1;
如果nums[len-1] >= target
,处理方式同上
class Solution {
public:
int search(vector<int>& nums, int target) {
int len = nums.size();
if (len == 0)
return -1;
if (nums[0] <= target) {
for (int i = 0; i < len; i++) {
if (nums[i] == target)
return i;
else if (nums[i] < nums[0])
return -1;
}
} else if (nums[len-1] >= target){
for (int i = len-1; i >= 0; i--)
if (nums[i] == target)
return i;
else if (nums[i] > nums[len-1])
return -1;
}
return -1;
}
};
方法二:
二分查找思想
class Solution {
public:
int search(vector<int>& nums, int target) {
int len = nums.size();
int begin = 0;
int end = len - 1;
while (begin <= end) {
if (nums[begin] == target)
return begin;
if (nums[end] == target)
return end;
int mid = (begin + end) / 2;
if (nums[mid] == target)
return mid;
if (nums[mid] < nums[begin]) {
if (target < nums[begin] && target > nums[mid])
begin = mid + 1;
else
end = mid - 1;
} else {
if (target < nums[mid] && target > nums[begin])
end = mid - 1;
else
begin = mid + 1;
}
}
return -1;
}
};