算法整理:二分查找

1二分查找:有序 集合搜索特定值的过程,每次比较之后将查找空间一分为二

target: 要查找的值 index: 当前位置 **left,right:**维持查找空间的指标

**mid:**用来确定向左查还是向右查的索引

**查找空间: [**left,right]

二分查找维护left,right,mid,并将target和索引为mid的值进行比较;

如果条件不满足或值不相等,则清除目标不可能存在的那一半,并在剩下的一半继续查找,直到成功为止

第一种情况:

cpp 复制代码
int bsearch(int l, int r):
    while (l < r)
        int mid = (l + r + 1)>>1;
        if (check(mid)) l = mid
        else r = mid - 1
    return l

第二种情况:右面第一个符合条件的下标。

注意讨论r=n-1的情况。

如果没有数符合条件,那么r最终就停在n-1的位置。

cpp 复制代码
int bsearch(int l, int r)
    while (l < r)
        int mid=l+(r-l)/2;
        if(check(mid))r = mid;
        else l=mid + 1;
    return l;

给定一个数组,需要判断数组长度。

比如访问到idx-1和idx+1时,长度必须大于等于3.

数组中查找数
cpp 复制代码
search(vector<int>& nums, int target) {
    l=0;
    r=n-1;
    while(l<=r)
       mid=l+(r-l)/2;
       if(target==nums[mid]) return mid;
       else if(target<nums[mid]) r=mid-1;
        else l=mid+1;
    return -1;
   
x的平方根

二分答案

cpp 复制代码
long long mySqrt(int x):
      if(x==0)return 0;
      if(x==1||x==2||x==3) return 1;
        //否则从2开始到x/2搜索哪个的平方等于x或者哪两个数的平方之间包含x
      long long l=2;//用long long类型防止溢出
      long long r=x/2;//平方只能在【2~x/2】中的某个数出现
      while(l<=r):
          long long mid=l+(r-l)/2;
          if(mid*mid==x||mid*mid<x&&(mid+1)*(mid+1)>x)//mid符合条件
          return mid;
          if (mid*mid<x) l=mid+1;
          else r=mid-1;
      return -1;

leetcode 33. 搜索旋转排序数组

cpp 复制代码
int search(vector<int>& nums, int target) {
    int l=0;
    int r=nums.size()-1;
    if(nums.size()==1&&nums[0]==target)return 0;
    if(nums.size()==1&&nums[0]!=target)return -1;
    while(l<r)
        int mid=l+(r-l)/2;
        if(nums[mid]<nums[0])r=mid;
        else l=mid+1;
    //r为右面第一个比nums[0]小的下标
    if(r==nums.size()-1&&nums[r]>nums[0])
        l=0;
        r=nums.size()-1;
    else
        if(target>=nums[0]) l=0; r--;
        else  l=r; r=nums.size()-1;
    while(l<r)
        int mid=l+(r-l)/2;
        if(nums[mid]>=target)r=mid;
        else l=mid+1;
    if(nums[r]==target)return r;
    return -1;
leetcode 852. 山脉数组的峰顶索引
cpp 复制代码
int peakIndex(vector<int>& arr)
        int l=0;
        int r=arr.size()-1;
        while(l<r)
            int mid=l+(r-l)/2;
            if(mid-1>=0&&mid+1<arr.size()&&arr[mid]<arr[mid-1]&&arr[mid]>arr[mid+1])r=mid;
            else l=mid+1;
        return r-1;
leetcode1095. 山脉数组中查找目标值

用二分法找到峰值(见上题)

while用if条件语句如果有访问数组索引+或-的操作,要防止数组越界。

cpp 复制代码
class Solution {
public:
    int findInMountainArray(int target, MountainArray &m) {
        int n=m.length();
        int l=0;
        int r=n-1;
        while(l<r){
             int mid=l+(r-l)/2;
             if(mid-1>=0&&mid+1<n&&m.get(mid)<m.get(mid-1)&&m.get(mid)>m.get(mid+1))r=mid;
             else l=mid+1;
        }
        int idx=r-1;//注意是r-1
        l=0;r=idx;
        while(l<r){
            int mid=l+(r-l)/2;
            if(m.get(mid)>=target)r=mid;
            else l=mid+1;
        }
        if(m.get(r)==target)return r;
        l=idx+1;r=n-1;
        while(l<r){
            int mid=l+(r-l)/2;
            if(m.get(mid)<=target)r=mid;
            else l=mid+1;
        }
        if(m.get(r)==target)return r;
        return -1;
    }
};
相关推荐
姚瑞南7 分钟前
【AI 风向标】四种深度学习算法(CNN、RNN、GAN、RL)的通俗解释
人工智能·深度学习·算法
补三补四29 分钟前
SMOTE 算法详解:解决不平衡数据问题的有效工具
人工智能·算法
RTC老炮1 小时前
webrtc弱网-RobustThroughputEstimator源码分析与算法原理
网络·算法·webrtc
听风吹等浪起1 小时前
分类算法-逻辑回归
人工智能·算法·机器学习
敲代码的嘎仔1 小时前
JavaWeb零基础学习Day2——JS & Vue
java·开发语言·前端·javascript·数据结构·学习·算法
yacolex2 小时前
3.3_数据结构和算法复习-栈
数据结构·算法
茉莉玫瑰花茶2 小时前
动态规划 - 两个数组的 dp 问题
算法·动态规划
微笑尅乐2 小时前
从暴力到滑动窗口全解析——力扣8. 字符串转换整数 (atoi)
算法·leetcode·职场和发展
火花怪怪2 小时前
LaMer结晶动力学模型
算法
legendary_bruce3 小时前
【22.2 增强决策树】
算法·决策树·机器学习