题目:
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
来自 https://leetcode.com/problems/search-in-rotated-sorted-array/
分析:
要求查找的时间复杂度为O(logN),常用的查找就是二分查找,时间复杂度就是这个,因此应该往转成二分查找的方向想。
方法1:
试试直接暴力的查找会怎么样
//beats 28%
int search(vector<int>& nums, int target) {
for(int i=0;i<nums.size();i++)
{
if(nums[i]==target)
return i;
}
return -1;
}
时间复杂度:O(N)
空间复杂度:O(1)
方法2:
基于二分查找,先找出旋转中心,这个相对简单,只要判断前后两个元素不是递增就可以。然后判断目标值在旋转中心的左、右哪个区间,最后对选定的区间进行二分查找。
//二分查找
int binarysearch(vector<int>&nums, int begin, int end,int target)
{
if (begin > end)
return -1;
else
{
int mid = (begin + end) / 2;
if (nums[mid] == target)
return mid;
else if (nums[mid] > target)
return binarysearch(nums, begin, mid-1, target);
else
return binarysearch(nums, mid+1, end, target);
}
}
//beats 99%
int search(vector<int>& nums, int target)
{
if (nums.size() == 0)return -1;
if (nums.size() == 1) return nums[0] == target?0:-1;
int L = nums.size(); int i = 0;int index = L-1;
while (i < L - 1)
{
if (nums[i] >= nums[i + 1]) { index = i; break; }
i++;
}
if (target >= nums[0])
return binarysearch(nums, 0, index, target);
else
return binarysearch(nums, index+1, L - 1, target);
}
时间复杂度:O(logN)
空间复杂度:O(1)
方法3:
比较取巧:和方法1类似,区别是有头脑的莽夫
int search(vector<int>& nums, int target) {
if(nums.size() == 0) return -1;
if(nums[0] == target) return 0;
if(nums.size() == 1 && nums[0] != target) return -1;
if(nums[0] < target){
for(int i = 1; i < nums.size(); ++i){
if(nums[i] == target) return i;
if(nums[i - 1] > nums[i]) return -1;
}
}
else{
for(int i = nums.size() - 1; i >= 1; --i){
if(nums[i] == target) return i;
if(nums[i - 1] > nums[i]) return -1;
}
}
return -1;
}