每日一题:leetcode81.搜索旋转排序数组Ⅱ

题目描述

在这里插入图片描述

题目分析

不含重复元素的题解(leetcode33)

这道题也是我们算法课的一道编程题,写完以后发现当时的思路和现在没有什么变化,果然是自己啊。我的想法是先判断区间整体是升序的还是旋转的,如果是升序的就按照正常的二分查找,如果是旋转的就判断中轴的落在了左半升区间还是右半升区间,问题的关键在于,旋转的数组不能简单因为target和中轴的大小判断是在左区间还是右区间,因此要分类讨论一下。总之,这个思路不是很好,因为没有有效利用端点的信息,如同官方题解所说,我们是可以直接判断出target在哪个区间的。每一次中轴会将数组分成两个部分,至少有一个部分是升序的,我们能够很简单的判断出target是否在那个升序数组中,从而决定在哪个半区间中查找。

我的思路代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        return bsearch(nums, target, 0, nums.size());
    }
private:
    int bsearch(vector<int>& nums, int target, int l, int r) {
        if (l == r) return -1;
        int mid = (l + r) >> 1;
        if (nums[mid] == target) return mid;
        if (nums[l] <= nums[r - 1]) {
            //升序区间
            if (nums[mid] > target) return bsearch(nums, target, l, mid);
            else return bsearch(nums, target, mid + 1, r);
        } else {
            //旋转区间
            if (nums[mid] >= nums[l]) {
                //中心点落在左边升序区间
                if (nums[mid] < target) return bsearch(nums, target, mid + 1, r);
                else {
                    int lr = bsearch(nums, target, l, mid);
                    int rr = bsearch(nums, target, mid + 1, r);
                    if (lr == -1) {
                        if (rr == -1) return -1; 
                        else return rr;
                    } else return lr;
                }
            } else {
                //中心点落在右边升序区间
                if (nums[mid] > target) return bsearch(nums, target, l ,mid);
                else {
                    int lr = bsearch(nums, target, l, mid);
                    int rr = bsearch(nums, target, mid + 1, r);
                    if (lr == -1) {
                        if (rr == -1) return -1; 
                        else return rr;
                    } else return lr;
                }
            }
        }
    }
};

按照官方题解写的代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l = 0, r = nums.size(), mid;
        while (l < r) {
            mid = (l + r) >> 1;
            if (nums[mid] == target) return mid;
            if (nums[mid] >= nums[l]) {
                //左半区间是升序
                if (target >= nums[l] && target < nums[mid]) r = mid;
                else l = mid + 1;
            } else {
                //右半区间是升序
                if (target > nums[mid] && target <= nums[r - 1]) l = mid + 1;
                else r = mid;
            }
        }
        return -1;
    }
};

刚才看了一下题解,发现它总是和nums[0]nums[n-1]比较,厉害。

含重复元素的题解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值