旋转排序数组被分成了前后两段有序的序列,其中nums[0]是分隔两段数组的中间值(或者nums[n-1])
则首先找到分隔点在哪里,接着和nums[0]比较大小,确定所处的序列在前还是在后,再进行二分查找。
注意二分查找的循环条件里需要取等号
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <map>
using namespace std;
/*
* 思路:旋转数组可以分为前后两部分,则首先应该确认在哪个部分,再使用二分查找即可
*
*/
class Solution {
public:
int search(vector<int>& nums, int target) {
if (nums[0] == target)
return 0;
// 用于标记旋转分隔的下标
int pos = 0, n = nums.size();
for (int i = 0; i < n - 1; i++)
{
if (nums[i] > nums[i + 1])
{
pos = i + 1;
break;
}
}
if (pos == 0)
pos = n;
// 用于二分查找
int left, right;
if (nums[0] > target)
{
left = pos;
right = n - 1;
}
else
{
left = 0;
right = pos - 1;
}
while (left <= right)
{
int mid = (left + right) / 2;
if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] == target)
return mid;
else right = mid - 1;
}
return -1;
}
};
int main()
{
int n, a, target;
cin >> n;
vector<int>nums;
for (int i = 0; i < n; i++)
{
cin >> a;
nums.push_back(a);
}
cin >> target;
Solution A;
cout << A.search(nums, target);
}