本题因为题目对原始的递增数组进行了部分旋转,因此普通的二分就不能用了,所以相比于普通的二分,这里的二分则是需要进行第一个元素与中间元素的大小对比,来判断前半部分还是后半部分是有序的,因为,一分为二之后,一定有一半是有序的,也就是递增的。判断完有序之后,就可以在有序的部分中继续判断目标值是否存在于当前区间,如果不在当前有序区间的话,就需要对左右指针进行重新计算,然后继续进行二分判断。
// 暴力算法可以直接解决本问题,但是起不到刷题的作用,因此还是用其他的方法完成本题较好
// class Solution {
// public:
// int search(vector<int>& nums, int target) {
// for (int i = 0; i < nums.size(); i++)
// {
// if (nums[i] == target)
// {
// return i;
// }
// }
// return -1;
// }
// };
class Solution {
public:
int search(vector<int>& nums, int target) {
int n = nums.size();
int left = 0, right = n - 1;
// 二分的时候左右指针最后有可能相等
while(left <= right)
{
int mid = (left + right) / 2;
if(nums[mid] == target)
return mid;
// 因为不知道那边是有序的,因此需要通过第一个元素与中间位置元素比较判断那边是有序的
// 如果确实小于的话,说明左半区有序,否则右半区有序
// 如果只有两个元素的话,那么nums[0]就是nums[mid],所以这里需要使用小于等于
if(nums[0] <= nums[mid])
{
// 如果目标值在当前范围内,那么只需要正常的二分即可
if(nums[0] <= target && target <= nums[mid])
right = mid - 1;
// 如果目标值不在其中,那么就需要将左指针移动到右边的下一个位置
else
left = mid + 1;
}
// 右半区有序的话,在有序的范围内进行二分
else
{
if(nums[mid] <= target && target <= nums[n - 1])
left = mid + 1;
else
right = mid - 1;
}
}
return -1;
}
};
文章讨论了一种针对旋转数组的二分查找算法,由于数组部分旋转,普通二分法不再适用。解决方案是通过比较首元素和中间元素确定有序区间,然后在有序区间内进行二分查找。如果目标值不在当前区间,则调整左右指针并继续二分,直到找到目标值或指针相遇。

被折叠的 条评论
为什么被折叠?



