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

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 分钟前
力扣:23.合并 K 个升序链表
算法·leetcode·链表
invicinble7 分钟前
这里对java的知识体系做一个全域的介绍
java·开发语言·python
wbs_scy22 分钟前
【Linux 线程进阶】进程 vs 线程资源划分 + 线程控制全详解
java·开发语言
re林檎25 分钟前
算法札记——4.27
算法
ss27336 分钟前
食谱推荐系统功能测试如何写?
java·数据库·spring boot·功能测试
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题】【Java基础篇】第15题:JDK1.7中HashMap扩容为什么会发生死循环?如何解决
java·开发语言·数据结构·后端·面试·哈希算法
数据牧羊人的成长笔记1 小时前
逻辑回归与Softmax回归
算法·回归·逻辑回归
try2find1 小时前
打印ascii码报错问题
java·linux·前端
014-code1 小时前
CompletableFuture 实战模板(超时、组合、异常链处理)
java·数据库
Nicander1 小时前
多数据源下@transcation事务踩坑
java·后端