LeetCode33——Search in Rotated Sorted Array
简单来说就是在数组中查找 输入的 target,如果找到返回索引,如果没有找到返回-1
在<algorithm>中STL提供find方法,虽然事先知道是O(n)复杂度的顺序查找,还是首先就试了试,结果是可以通过的
注:返回的是迭代类型。
代码:
class Solution {
public:
int search(vector<int>& nums, int target) {
auto it = find(nums.begin(),nums.end(),target);
return it==nums.end()?-1:it-nums.begin();
}
};
不过无聊的我顺便查了查find()的源码,并把它弄过来稍微改了改,肯定也是能够通过的。
class Solution {
public:
int search(vector<int>& nums, int target) {
auto first = nums.begin();
while (first != nums.end())
{
if (*first == target)return first - nums.begin();
first++;
}
return -1;
}
};
不过这个题肯定不能就这么水过了,毕竟也是hard难度了。
脑补一下之前的查找方式,二分查找的时间复杂度是O(logn)。
但是问题又来了,二分查找对查找序列的要求是:线性表必须采用顺序存储,并且关键字有序(通常是从小到大)。
本题的序列可以看做是由递增序列“循环右移”得到。怎么把二分查找应用到这个有特点的序列中呢?
我的思路是:
1.首先对于对于这样一个序列 5 6 7 8 9 1 2 3 4,它可以被分为两部分:最大值9左边和右边,这样,两个序列就是分别有序了。
2.然后我们首先找到最大值的索引,分别对着两个序列进行二分查找。最后返回结果即可。
基于我的思路关键就是找序列的最大值。这里我参考了,《编程之美》中的分治法。
最终代码如下:
class Solution {
private:
int BinaryFindMax(vector<int>nums, int low, int high)//找到最大值的索引
{
if (high - low <= 1)
{
if (nums[high]>nums[low])
return high;
else
return low;
}
int maxIndexL = BinaryFindMax(nums, low, low + (high - low) / 2);//递归左边
int maxIndexR = BinaryFindMax(nums, low + (high - low) / 2 + 1, high);//递归右边
int maxIndex = nums[maxIndexL] > nums[maxIndexR] ? maxIndexL : maxIndexR;//取两者较大的的索引
return maxIndex;
}
int BinarySearch(vector<int>nums, int low, int high, int target)//二分查找
{
while (low <= high)
{
int mid = (low + high) / 2;
if (target == nums[mid])
{
return mid;
}
else if (target > nums[mid])
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
return -1;//如果没找到则返回-1
}
public:
int search(vector<int>& nums, int target) {
int index = BinaryFindMax(nums, 0, nums.size() - 1);//找到最大值的索引
if (nums[index] == target)//如果target就是最大值
return index;
int leftIndex = BinarySearch(nums, 0, index, target);//二分查找最大值左边的子序列
int rightIndex = BinarySearch(nums, index + 1, nums.size() - 1, target);//二分查找最大值右边的子序列
return (leftIndex == -1) ? rightIndex : leftIndex;
}
};