二刷LeetCode--33. 搜索旋转排序数组(C++版本)有趣的变样式二分查找

文章讨论了一种针对旋转数组的二分查找算法,由于数组部分旋转,普通二分法不再适用。解决方案是通过比较首元素和中间元素确定有序区间,然后在有序区间内进行二分查找。如果目标值不在当前区间,则调整左右指针并继续二分,直到找到目标值或指针相遇。

本题因为题目对原始的递增数组进行了部分旋转,因此普通的二分就不能用了,所以相比于普通的二分,这里的二分则是需要进行第一个元素与中间元素的大小对比,来判断前半部分还是后半部分是有序的,因为,一分为二之后,一定有一半是有序的,也就是递增的。判断完有序之后,就可以在有序的部分中继续判断目标值是否存在于当前区间,如果不在当前有序区间的话,就需要对左右指针进行重新计算,然后继续进行二分判断。

// 暴力算法可以直接解决本问题,但是起不到刷题的作用,因此还是用其他的方法完成本题较好
// 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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值