LeetCode 之 Search for a Range — C++ 实现

Search for a Range

Given a sorted array of integers, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

给定一个有序的整型数组,找出给定目标值在数组中的起始位置和终止位置。

算法时间复杂度要求为 O(logn).

如果目标值未在数组中,返回[-1, -1]  

例如,

给定数组[5, 7, 7, 8, 8, 10] 和目标值 8,返回[3, 4]

分析:

二分查找。

实现1:

    先用二分法找到一个值,然后在这个值的左、右利用上次的上(high)下(low)界,分别在 low 和 mid 以及 mid 和 high 之间再进行二分查找。

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int low = 0, high = nums.size()-1;
        int mid = 0, lmid = 0, rmid = 0;
        int  left = 0, right = 0;
        int isfind = 0; //存在标志
        
        vector<int> returnSize(2, -1);
        if(nums.empty()) //空指针或空数组
        {
            return returnSize;
        }
        
        while(low <= high) //二分查找
        {
            mid = (low + high)/2;
            if(nums[mid] == target) //找到一个匹配节点
            {
                isfind = 1;
                break;
            }
            else if(nums[mid] < target)
            {
                low = mid + 1;
            }
            else
            {
                high = mid - 1;
            }
        }
        
        if(isfind)
        {
            left = mid;
            while(low <= left)//二分找左边界
            {
                lmid = (low + left)/2;
                if(nums[lmid] == target)
                {
                    if(lmid-1 >= low)
                    {
                        if(nums[lmid-1] == target)
                        {
                            left = lmid - 1;
                        }
                        else
                        {
                            returnSize[0] = lmid;
                            break;
                        }
                    }
                    else
                    {
                        returnSize[0] = lmid;
                        break;
                    }
                }
                else
                {
                    low = lmid + 1;
                }
            }
            
            right = mid;
            while(right <= high)//二分找右边界
            {
                rmid = (right + high)/2;
                if(nums[rmid] == target)
                {
                    if(rmid+1 <= high)
                    {
                        if(nums[rmid+1] == target)
                        {
                            right = rmid + 1;
                        }
                        else
                        {
                            returnSize[1] = rmid;
                            break;
                        }
                    }
                    else
                    {
                        returnSize[1] = rmid;
                        break;
                    }
                }
                else
                {
                    high = rmid - 1;
                }
            }
        }
        
        return returnSize;
        
    }
};
 

实现2:

     对左、右范围位置分别进行二分查找。查找左范围时,当mid位置的值小于等于 target 时,向左边查找;查找又范围时,当mid值大于等于 target 时,向右边查找。

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int low = 0, high = nums.size()-1;
        int lmid = 0, rmid = 0;
        
        vector<int> returnSize(2, -1);
        if(nums.empty()) //空指针或空数组
        {
            return returnSize;
        }
        
        while(low <= high) //对左边界进行二分查找
        {
            lmid = (low + high)/2;
            if(nums[lmid] < target)
            {
                low = lmid + 1;
            }
            else
            {
                high = lmid - 1;
            }
        }
        if(nums[low] != target)//没找到
        {
            return returnSize;
        }
        else
        {
            returnSize[0] = low;
        }
        
        low = 0;
        high = nums.size()-1;
        while(low <= high) //对右边界进行二分查找
        {
            rmid = (low + high)/2;
            if(nums[rmid] <= target)
            {
                low = rmid + 1;
            }
            else
            {
                high = rmid - 1;
            }
        }
        returnSize[1] = high;
        
        return returnSize;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值