leetcode 打码记录
leetcode 33. 搜索旋转排序数组
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [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
解题思路
这道题出发点是时间复杂度是 O(log n) 级别,说明了我们需要用2分法搜索数组,也就是说在每次循环时要确定下一次选择的哪一边作为搜索范围。本题采用双指针进行范围选择,i, j分别指向数组的头与尾,思路如下:
1. 一个旋转排序数组,可能包含的值val的范围是val>=nums[i], 或者val<=nums[j]。
2. if target == nums[i] || target == nums[j],搜索结束,返回i或j; if target
class Solution {
public:
int search(vector<int>& nums, int target) {
int i = 0;
int j = nums.size()-1;
if(j < 0){ return -1;}
if(j == 0){
if(nums[0]!=target){ return -1;}
else { return 0;}
}
while(i<j){
if(nums[i]==target){ return i;}
if(nums[j]==target){ return j;} // target搜索结束,返回i或j
if(target < nums[i] && target >nums[j]){ break;} // 当前的数组中不可能包含target,结束搜索
if(j-i<=1){ break;}
int n = (i+j)
if(nums[n]>=target){ // 说明要搜索比nums[n]小的数
if(nums[i]<=nums[n]){ // 从i到n是递增序列,则nums[n]左边全比nums[n]小
if(nums[i]<=target){ // 左边可能包括target,则下次搜索左边
j = n;
}
else{ // 左边不可能包含target,则下次搜索右边
i = n;
}
}
else{ // 从i到n不是递增序列,则nums[n]右边全比nums[n]大,因此下次范围左边
j = n;
}
}
else{ // 说明要搜索比nums[n]大的数
if(nums[i]<=nums[n]){ // 从i到n是递增序列,则nums[n]左边全比nums[n]小,因此搜索右边
i = n;
}
else{ // 从i到n不是递增序列,则nums[n]右边全比nums[n]大
if(nums[j]>=target){ // 右边可能包括target,则下次搜索范围为右边
i = n;
}
else{ // 否则搜索左边
j = n;
}
}
}
}
return -1;
}
};