Search in Rotated Sorted Array
难度:Hard
Suppose a sorted array 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.
(下一题将研究存在重复的情况Search in Rotated Sorted Array II)
解题思路:
对于数组搜索问题,时间复杂度大致有三种O(n),O(lg n),O(1)
其中线性复杂度 O(n),即顺序搜索;而常数时间O(1)一般通过关键字索引或Hash表实现;而对数复杂度O(lg n),常通过二分查找、二叉搜索树类型实现
对于本题中的条件是有序数组的变形,因此可联想到“快速排序的选择”–二分查找
而难点就是寻找划分元素和对划分元素左右两侧的递归条件及其边界。
对于划分元素,容易想到直接取中间 m = (l+r) / 2;
数组边界 [l, r)
对实例观察:
0 1 2 4 5 6 7
4 5 6 7 0 1 2
5 1 3
3 1
nums[m] > nums[l] : (l, m-1)单增
nums[m] <= nums[l] : (m+1, r)单增
注:
- 当数组取边界 [l, r) 时,m取到居中靠右(如在2个元素时,m = 1),因此此时,应该比较nums[m], num[l]
- 当取数组边界 [l, r] 时,m取到居中靠左(如在2个元素时,m = 0),因此此时,应该比较nums[m], num[r];
数组边界为 [l,r) – O(lg n)
class Solution {
public:
//nums 数组边界为 [l,r)
int searchR(vector<int>& nums,int l, int r, int target) {
if (r <= l)
return -1;
int m = (l+r) / 2;
if (nums[m] == target)
return m;
if (nums[l] < nums[m]) {
if (target >= nums[l] && target < nums[m])
return searchR(nums, l, m, target);
else
return searchR(nums, m+1, r, target);
} else {
if(target > nums[m] && target <= nums[r-1])
return searchR(nums, m+1, r, target);
else
return searchR(nums, l, m, target);
}
}
int search(vector<int>& nums, int target) {
return searchR(nums, 0, nums.size(), target);
}
};
数组边界[l, r] –注意传入数组的边界
class Solution {
public:
//nums 数组边界为 [l,r]
int searchR(vector<int>& nums,int l, int r, int target) {
if (r < l)
return -1;
int m = (l+r) / 2;
if (nums[m] == target)
return m;
if (nums[r] > nums[m]) {
if (target > nums[m] && target <= nums[r])
return searchR(nums, m+1, r, target);
else
return searchR(nums, l, m-1, target);
} else {
if(target >= nums[l] && target < nums[m])
return searchR(nums, l, m-1, target);
else
return searchR(nums, m+1, r, target);
}
}
int search(vector<int>& nums, int target) {
return searchR(nums, 0, nums.size()-1, target);
}
};
顺序搜索O(n) – 不推荐
class Solution {
public:
int search(vector<int>& nums, int target) {
int i = 0;
for (; i < nums.size(); i++) {
if (nums[i] == target)
break;
}
if(nums.size() == i)
return -1;
else
return i;
}
};
(下一题将研究存在重复的情况Search in Rotated Sorted Array II)