leetcode题目 二分查找升级版

题目: 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].
思路: 两种方法,一种是在普通的二分查找到目标元素后线性向前和向后探测,找到相同元素的第一个和最后一个位置。第二种方式是找到目标元素后依然采用二分查找的方式向前和向后探测,找到第一个和最后一个位置。第二种方法的边界控制比较复杂。

解法一:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> result(2,-1);
        int fir=0;
        int sec=nums.size()-1;
        int mid;
        while(fir<=sec)
        {
            mid=(fir+sec)/2;
            if(nums[mid]>target)
                sec=mid-1;
            else if(nums[mid]<target)
                fir=mid+1;
            else
            {
                auto temp=mid;
                while(--temp>=0&&nums[temp]==nums[mid]);
                    result[0]=(temp+1);
                temp=mid;
                while(++temp<nums.size()&&nums[temp]==nums[mid]);
                    result[1]=(temp-1);
                return result;
            }
        }
        return result;
    }
};

运行通过,但是只击败了11%的代码。
这里写图片描述

解法二:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> result(2, -1);
        int fir = 0;
        int sec = nums.size() - 1;
        int mid;
        while (fir <= sec)
        {
            mid = (fir + sec) / 2;
            if (nums[mid]>target)
                sec = mid - 1;
            else if (nums[mid]<target)
                fir = mid + 1;
            else
            {
                result[0] = searchFirst(nums, fir, mid,target);
                result[1] = searchLast(nums, mid, sec,target);
                return result;
            }
        }
        return result;
    }
    int searchFirst(vector<int>& nums, int fir, int sec,int target)
    {
        int mid;
        while (fir <= sec)
        {
            mid = (fir + sec) / 2;
            if (nums[mid] >= target)
                sec = mid-1;
            else if (nums[mid]<target)
                fir = mid + 1;
        }
        //算法的精髓,返回的并不是mid而是fir,也可以写为return sec+1;
        return fir;
    }
    int searchLast(vector<int>& nums, int fir, int sec,int target)
    {
        int mid;
        while (fir <= sec)
        {
            mid = (fir + sec) / 2;
            if (nums[mid]>target)
                sec = mid - 1;
            else if (nums[mid] <= target)
                fir = mid + 1;
        }
        //算法的精髓,返回的并不是mid而是sec,也可以写为return fir-1;
        return sec;         
    }
};

解法二的效率在大数据的时候应该效率更高,但是在leetcode上测试时运行时间和解法一的一样。

附加题目: Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You may assume no duplicates in the array.

Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0

思路: 这题考查的和上边的寻找第一个位置比较类似。要时刻注意fir指针和sec指针的变化情况以及跳出循环时它们指向的位置。

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int fir=0,sec=nums.size()-1,mid=0;
        while(fir<=sec)
        {
            mid=(fir+sec)/2;
            if(nums[mid]<target)
                fir=mid+1;
            else if(nums[mid]>target)
                sec=mid-1;
            else
                return mid;
        }
        //fir会指向插入的位置,sec在fir前一个位置
        return fir;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值