算法整理:二分查找

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;
    }
};
相关推荐
带多刺的玫瑰1 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
爱敲代码的憨仔1 小时前
《线性代数的本质》
线性代数·算法·决策树
yigan_Eins1 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法
阿史大杯茶1 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
დ旧言~2 小时前
【高阶数据结构】图论
算法·深度优先·广度优先·宽度优先·推荐算法
张彦峰ZYF2 小时前
投资策略规划最优决策分析
分布式·算法·金融
The_Ticker2 小时前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
爪哇学长3 小时前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
Dola_Pan3 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法
繁依Fanyi3 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse