题目:
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.
假设数组中不存在重复的数,要求查找一个数,如果不存在,则返回-1。
举例:
4 5 6 7 0 1 2, 3 ----> -1
4 5 6 7 0 1 2, 5 ----> 1
思路:
可以直接One pass就可以找到结果,但是显然这样做就没有意义了,能想到的方法是二分查找,但是现在数组不满足sorted的要求,所以不能轻易的使用二分法,要加一些变动。
如果某个元素的索引为center,tail为数组的最后一个元素的索引,head为数组的第一个元素的索引,则如果nums[center]<nums[tail],则从center到tail都是升序的。如果nums[center]>nums[head],那么从head到center都是升序的。根据这一点,可以将数组掰正。
代码:
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
int search(vector<int>& nums, int target)
{
int size = nums.size();
if(size == 0) return -1;
int head = 0,tail = size - 1,center = 0;
while(head < tail - 1)
{
center = (head + tail) / 2;
if(target == nums[center])return center;
if(nums[center] < nums[tail])//right part is normal
{
if(target < nums[center])tail = center;
else
{
if(target == nums[tail])return tail;
if(target > nums[tail])tail = center;
else head = center;
}
}
else//left part is normal
{
if(target > nums[center])head = center;
else
{
if(target == nums[head])return head;
if(target < nums[head])head = center;
else tail = center;
}
}
}
if(nums[head] == target)return head;
else if(nums[tail] == target)return tail;
return -1;
}
int main()
{
vector<int> nums;
nums.push_back(1);
cout<<search(nums,3)<<endl;
return 0;
}
时间复杂度:
O(logn)。
空间复杂度:
O(1)。