Leetcode笔记目录
一、题目描述
给你一个升序排列的整数数组 nums ,和一个整数 target 。
假设按照升序排序的数组在预先未知的某个点上进行了旋转。(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
nums 中的每个值都独一无二。
示例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.思想
二分法解决问题,但数组不是有序的,而是局部有序的,本题最好的做法是用全程用二分(速度logn),要特别注意边界条件的判断:
- 首先二分法找到目标值所处的有序区间,然后在有序区间上找目标值;
- 这两次二分是可以同时完成的。
- 本题用的左闭右闭[0,size-1]模板,因为会使用nums[right],左闭右开会越界。
2.代码
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1,mid;
while(left<=right){
mid = left+(right-left);
if(nums[mid]==target)return mid;
else if(nums[mid]>=nums[left]){ //等号是因为mid可能和left重合
if(target>=nums[left]&&target<nums[mid]) right = mid - 1;
else left = mid + 1;
}
else{
if(target>nums[mid]&&target<=nums[right]) left = mid + 1;
else right = mid - 1;
}
}
return -1;
}
左闭右闭模板:
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1,mid;
while(left<=right){
mid = left+(right-left);
if(nums[mid]==target)return mid;
else if(target<nums[mid]){
right = mid - 1;
}
else{
left = mid + 1;
}
}
return -1;
}
三、总结
难点在于怎么将两个二分过程用一个解决,注意边界条件的判断。