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

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;

    }
};
相关推荐
牧瀬クリスだ几秒前
Java线程——从创建第一个线程到休眠线程
java·开发语言
清水白石0082 分钟前
从“点一下导出”到生产级任务队列:Python 异步导出系统设计全景解析
java·数据库·python
Mahir082 分钟前
Spring 核心原理:IoC/DI 与 Bean 生命周期全景解析
java·后端·spring·面试·bean生命周期·控制反转ioc·依赖注入di
weixin_489690023 分钟前
NAS部署实测:Solon vs Spring Boot,从内存到包体积的“降维打击”
java·spring boot·后端
重生之我是Java开发战士6 分钟前
【贪心算法】柠檬水找零,将数组和减半的最少操作次数,最大数,摆动序列, 最长递增子序列,递增的三元子序列
算法·贪心算法
Godspeed Zhao6 分钟前
从零开始学AI17——SVM的数学支撑知识
算法·机器学习·支持向量机
我爱cope8 分钟前
【力扣hot100:53. 最大子数组和】
算法·leetcode·职场和发展
枕星而眠10 分钟前
数据结构哈希表(散列表)超详细总结
c语言·数据结构·后端·散列表
tongluowan00710 分钟前
怎么保证缓存和数据库的一致性
java·数据库·缓存·一致性
一条泥憨鱼10 分钟前
【Java 进阶】LinkedHashMap 与 TreeMap
java·开发语言·数据结构·笔记·后端·学习