算法篇二----二分查找

1、

分析:a、x<t---->left = mid+1

b、x>t------>right = mid -1

c、x=t----->返回结果

细节问题:a、循环结束的条件

left<right

b、时间复杂度logN

cpp 复制代码
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0,right=nums.size()-1;
        while(left<=right)
        {
            int mid = left+(right-left)/2;
            if(nums[mid]<target)
            left=mid+1;
            else if(nums[mid]>target)
            right=mid-1;
            else
            return mid;
        }
        return -1;
        
    }
};

那么就可以总结模板

cpp 复制代码
while(left<=right)
{
    int mid = left+(right-left)/2;
    if(...)
    left=mid+1;
    else if(...)
    right=mid-1;
    else
    return ...;
}

注意二段性

2、

一、查找区间的左端点

根据二段性

1>x<t---->left = mid+1----->left,right

2>x>=t------>right = mid------>left,right

这就是本题思路,但是重点不在这里

细节处理:1>循环条件(left<right)

left<=right 大错特错

分析:a、有结果 b、全大于t c、全小于t

相等时,就是最终结果,无需判断,最坑人的就是,只要判断就会死循环,求中间值依旧是ret,ret不会移动,命中第2>条件,一直循环

2>求中点操作

left+(right-left)/2

二、查找右端点

1>x<t---->left = mid----->left,right

2>x>=t------>right = mid-1------>left,right

细节问题同上

cpp 复制代码
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(nums.size()==0)
        return {-1,1};

        int begin =0;
        int left=0,right = nums.size()-1;
        while(left<right)
        {
            int mid = left+(right-left)/2;
            if(nums[mid]<target)
            left=mid+1;
            else
            right=mid;
        }
        if(nums[left]!=target)
        return {-1,1};
        else 
        begin left;

        int left=0,right=nums.size()-1;
        while(left<right)
        {
            int mid = left +(right-left+1)/2;
            if(nums[mid]<=target)
            left=mid;
            else
            right = mid-1;
        }
        return {begin,right};
    }
};

查找区间左端点的模板

cpp 复制代码
     while(left<right)
        {
            int mid = left+(right-left)/2;
            if(...)
            left=mid+1;
            else
            right=mid;
        }

查找区间右端点的模板

cpp 复制代码
while(left<right)
        {
            int mid = left+(right-left+1)/2;
            if(...)
            left=mid;
            else
            right=mid-1;
        }

小技巧:当下面出现-1的时候,上面就+1

以上就是二分查找的模型,再用几个例题加深理解

3、

cpp 复制代码
class Solution {
public:
    int mySqrt(int x) {
        if(x<1)
        return 0;
        int left = 1,right=x;
        while(left<right)
        {
            int mid = left+(right-left+1)/2;
            if(mid*mid<=x)
            left=mid;
            else
            right= mid-1;
        }
        return left;

    }
};

4、

cpp 复制代码
         
class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int left = 1,right=arr.size()-2;
        while(left<right)
        {
            int mid =left+(right-left+1)/2;
            if(arr[mid]>arr[mid-1])
            left=mid;
            else
            right=mid-1;
        }
        return left;

    }
};
相关推荐
考虑考虑2 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯3 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路7 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
先吃饱再说8 小时前
判断回文字符串,从一行代码到双指针优化
算法
像我这样帅的人丶你还10 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
黄敬峰11 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
plainGeekDev12 小时前
GreenDAO → Room
android·java·kotlin
得物技术12 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六16 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程