问题描述:
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,1,2,4,5,6,7]
might become [4,5,6,7,0,1,2]
).
You are given a target value to search. If found in the array return its index, otherwise return -1
.
You may assume no duplicate exists in the array.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2]
, target = 0
Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2]
, target = 3
Output: -1
题目大意就是一个排序的vector被平移了n位,给定这个向量和目标值,查找目标值在向量中的下标,若没有下标,就返回-1。
解题思路:
本文采用递归的方法,逻辑简单,但是会占用更多的内存空间(也可改为循环)。
定义一个find函数用于查找元素位置:find_index(vector<int>& nums, int left, int right, int target)
第一个形参是向量,第二是查找的左边界,第三个是查找的有边界,第四个是目标值。(有点类似于二分查找)
首先将中间值和右边界的值比较,若中间值小于后边界值,则说明右半部分是有序的。此时若target比中间值大且比右边界值小,则需要在右半部分查找;否则在左半部分。
若中间值大于等于后边界值,则说明左半部分是有序的。此时若target比中间值小且比左边界大,则需要在左半部分查找;否则在右半部分。
边界条件是left>right,此时说明不存在target,返回-1。
源码:
class Solution {
public:
int find_index(vector<int>& nums, int left, int right, int target){
if(left>right) return -1;
// cout<<left<<" "<<right<<endl;
int med = (left + right) / 2;
if(nums[med] == target) return med;
if(nums[med]<nums[right]){
if(nums[med]<target && target<=nums[right])
left = med+1;
else
right = med-1;
}
else{
if(nums[left]<=target && target<nums[med])
right = med-1;
else
left = med+1;
}
return find_index(nums, left, right, target);
}
int search(vector<int>& nums, int target) {
int N = nums.size();
int index = find_index(nums, 0, N-1, target);
return index;
}
};