4.4旋转数组查找数字
题目描述
一个原本增序的数组被首尾相连后按某个位置断开(如【1,2,2,3,4,5】->【2,3,4,5,1,2】为在第一位和第二位断开),我们称其为旋转数组。给定一个值,判断这个值是否存在于这个旋转数组中
输入输出样例
Input:nums = [2,5,6,0,0,1,2], target = 0
Output:true
输入一个数组和一个值,输出一个bool值。
题解
跟之前的题目大差不差,是类似两个数组都是递增的然后拼接一块。不过这个题里面的两个数组都是有序的且把这两个小数组拼接在一起也是有序的。所以仍然可以使用二分查找。对于当前的中点,如果它指向的值小于等于右端,那么就说明右边排好序了,反之,左边排好序。如果target在排好序的区间里了,那就可以在区间里进行二分查找。反之,对另一半的区间查找。
这里面有个小问题,就是可能数组存在重复的数组,要是中点和左端数字相同,就不能确定左右的数组情况,没准都是相同数字,也没准左边的小数组都跟中点相同。这个时候就给左端点向右移动一个,也不耽误整体的二分查找。因为他跟中点相同。
cpp
#include <iostream>
#include <vector>
using namespace std;
bool search(vector<int>& nums, int target) {
int start = 0, end = nums.size() - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
return true;
}
if (nums[start] == nums[mid]) {
//不知道哪个区间是增序
++start;
}
else if(nums[mid] <= nums[end]) {
//右区间是增序
if (target > nums[mid] && target <= nums[end]) {
start = mid + 1;
}
else {
end = mid - 1;
}
}
else {
//左区间是递增的
if (target >= nums[start] && target < nums[mid]) {
end = mid - 1;
}
else {
start = mid + 1;
}
}
}
return false;
}
int main() {
vector<int> nums = { 5,7,7,8,8,10 };
int target = 8;
if (search(nums, target)) {
cout << "true" << endl;
}
else {
cout << "false" << endl;
}
return 0;
}