日常算法刷题——力扣34

##2023/3/3 刷算法的第二天

针对力扣的704题:本题是二分查找的基本使用!在此需要注意二分查找的基本特点:
1.数列基本有序;
2.数列数据内容不可重复。

此题一试便知可以暴力求解

但是暴力求解的时候,看样列知道还有一种可能是vector为空,此种情况应该单独拿出来讨论,不然就会指针越界报错!

class Solution {
    
    
public:
    vector<int> searchRange(vector<int>& nums, int target) {
    
    
        //暴力求解
        int left=-1,right=-1;
        if(!nums.size())
        {
    
    
            return {
    
    left,right};
        }
        for(int i=0;i<=nums.size()-1;i++)
        {
    
    
            if(nums[i]==target)
             {
    
     
                 left=i;
                  i=nums.size();
             }
        }
        for(int j=nums.size()-1;j>=0;j--)
        {
    
    
            if(nums[j]==target)
               {
    
     
                   right=j;
                   j=-1;
               }

        }
        return {
    
    left,right};
    }
};

求解方法二:二分查找法:
使用二分查找的时候就把左右分开来找,时间复杂度依旧是O(log n)的。
算法思想(以找左边界为例):思考,原二分查找算法是分为三种情况的,那我们在分开找的时候就可以想想如何利用这三种情况一次就找到?比如找左边的时候,就可以先二分,然后一直向左走。那么如何一直向左走呢?方法就是改变判断方式——即我们只需要将原来二分查找的大于和等于合二为一,条件成立就使得right变为mid-1,以此即可实行一直左走的目的。右边也是如此,代码如下:

class Solution {
    
    
public:
    //二分查找
    vector<int> searchRange(vector<int>& nums, int target) {
    
    
        int LL=last_Left(nums,target);
        int RR=last_Right(nums,target);
        return {
    
    LL,RR};
    }

private:
    int last_Left(vector<int>&nums,int target)  // 左边
    {
    
    
        int left=0,right=nums.size()-1;
        int Left=-1;
        while(left<=right)
        {
    
    
            int mid=(left+right)/2;
            if(nums[mid]>=target)       //大或者是等都向左走
            {
    
    
                right=mid-1;
                if(nums[mid]==target)
                    Left=mid;
            }
            else
                left=mid+1;
        }
        return Left;
    }

    int last_Right(vector<int>&nums,int target)
    {
    
    
        int left=0,right=nums.size()-1;
        int Right=-1;
        while(left<=right)
        {
    
    
            int mid=(left+right)/2;
            if(nums[mid]<=target)       //小或者是等都向右走
            {
    
    
                left=mid+1;
                if(nums[mid]==target)
                    Right=mid;
            }
            else
                right=mid-1;
        }
        return Right;
    }
}
;

当然此种写法也有不足之处,既是内存使用过多。不过对于现在的水平,能写出来就已经心满意足了,日后当能力大涨之后又来弥补吧!

猜你喜欢

转载自blog.csdn.net/m0_55704585/article/details/129318356