LeetCode:寻找范围

题目描述:给定一个有序数组(如[5, 7, 7, 8, 8, 10]),以及一个目标值(target=8),找出这个目标值在数组中的范围(结果是[3,4]),要求的时间复杂度为O(logN),N表示数组的长度。

1、递归解法:比较中间元素(下标为mid)与target的大小,可能出现三种情况,即中间元素等于 target,中间元素小于 target,中间元素大于 target,下面我们分情况讨论:

情况1:nums[mid]==target,则[left, right]中的left可能在序列的前半段中,right可能在序列的后半段,接下来我们可以解决原问题的两个子问题:

子问题1在序列的前半段中找[left_1,right_1],这个left_1一定是最终的left,而right_1一定等于前面的mid;

子问题2在序列的后半段中找[left_2,right_2],这个right_2一定是最终的right,而left_2一定等于前面的mid;

待两个子问题解决后,原问题的解就是[left_1, right_2];

情况2:nums[mid] < target,则[left,right]一定在半段序列中,所以我们只需解决子问题2,得到的结果就是原问题的结果;

情况3:nums[mid] > target,则[left,right]一定在半段序列中,所以我们只需解决子问题1,得到的结果就是原问题的结果;

代码如下:

vector<int> searchRange(vector<int>& nums, int target) {

        vector<int> res;
        int size = nums.size();

        int s = size, e = -1;
        searchRange(nums,target,0,size-1,s,e);

        if(s==size && e==-1) {
            res.push_back(-1);
            res.push_back(-1);
            return res;
        }
        else{
            res.push_back(s);
            res.push_back(e);
            return res;
        }
}

void searchRange(vector<int>& nums, int &target, int low,int high,int &s,int &e){
        // s代表left, e代表right
        if(low>high) return ;
        int mid = (low+high)/2;

        if(nums[mid]==target){
            searchRange(nums,target,low,mid-1,s,e);
            searchRange(nums,target,mid+1,high,s,e);

            s = mid<s? mid:s;
            e = mid>e? mid:e;
        }
        else if(nums[mid]<target){
            searchRange(nums,target,mid+1,high,s,e);
        }
        else
            searchRange(nums,target,low,mid-1,s,e);
}

2、迭代解法,这个更直观一点,先找left,再找right,代码如下:

vector<int> searchRange(vector<int>& nums, int target) {
    int start = 0, end = nums.size(), mid, left, right;
    while (start < end) {
        mid = (start + end) / 2;
        if (nums[mid] >= target)
            end = mid;
        else
            start = mid + 1;
    }
    left = start; // 找到了left

    start = 0, end = nums.size();
    while (start < end) {
        mid = (start + end) / 2;
        if (nums[mid] > target)
            end = mid;
        else
            start = mid + 1;
    }
    right = start;// 找到了right
    return left == right ? vector<int> {-1,-1} : vector<int> {left,right-1};
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值