[Leetcode]_34 Search for a Range

/**
 *  Index: 34
 *  Title: Search for a Range
 *  Author: ltree98
 **/


题意是,给一个增序数组,求目标数字在数组中的位置,没有则为[-1, -1]。
当然,可以用穷举;
但是,题目中要求时间复杂度为 O(logn),
很显然的就想到二分了。

对了,还有一点就是目标数字,可能有 0个,1个,2个 … n个
所以,当找到目标值以后,还要向前,向后遍历,来找起始位置和结束位置。
但是,不可能出现中间掺杂其他数字的情况,因为它们是增序数组。


二分+前后遍历

这个方法,就是先通过二分查找,来找到其中一个,
然后,因为是增序的,所以向前后遍历,直到非目标值。


class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int l = 0, h = nums.size()-1;
        int mid = (l+h)/2;

        while(l <= h)   {
            if(nums[mid] > target)  h = mid-1;
            else if(nums[mid] < target) l = mid+1;
            else    {
                int start = mid-1, end = mid+1;
                while(start >= 0 && nums[start] == target)  --start;
                while(end < nums.size() && nums[end] == target)     ++end;
                return {start+1, end-1};
            }
            mid = (l+h)/2;
        }
        return {-1, -1};
    }
};


二分

这个方法,就是通过两次二分查找,不断逼近到目标值,从而来找到目标值的首尾两个序号。
如果首尾序号值相同,则说明目标值不存在于数组中。


class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int start, end;
        int l, h, mid;

        l = 0, h = nums.size()-1;
        while(l < h)    {
            mid = (l+h)/2;
            if(target <= nums[mid]) h = mid;
            else    l = mid+1;  
        }
        start = l;

        l = 0, h = nums.size()-1;
        while(l < h)    {
            mid = (l+h)/2;
            if(target >= nums[mid]) l = mid+1;
            else    h = mid;
        }
        end = l;

        if(start == end)    return {-1, -1};
        else    return {start, end-1};
    }
};
发布了472 篇原创文章 · 获赞 387 · 访问量 78万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览