二分查找第一弹

简介: 二分查找第一弹

1.特点

细节多,不好写,容易死循环->掌握之后编程最简单的算法

2.学习中的侧重点

1.算法原理

数组有一个规律,他们就可以使用二分的情况,两段性(通过一个规律,发现可以把数组分成两部分)

2.模版

不去死记硬背->理解后再记忆。

1.朴素的二分->最简单->有局限性

2.查找左边界的二分模版  查找右边界的二分模版

万能且好用,细节多

力扣704.二分查找

太简单了,懒得写题解啦

class Solution {
    public int search(int[] nums, int target) {
        int begin=0;
        int end=nums.length-1;
        int med;
    for(int i=0;i<nums.length;i++){
        med=(begin+end)/2;
        if(nums[med]==target){
         return med;
        }
        if(nums[med]<target){
        begin=med+1;}
        if(nums[med]>target){
        end=med-1;}
 
    }
    return -1;
    }
}
class Solution {
       public static int search(int[] nums, int target) {
        int begin=0;
        int end=nums.length-1;
        int med;
//没啥大必要,但是也可以这么做
        for(int i=0;i<nums.length;i++){
//begin和end,看谁大谁小,假如begin>end那就说明不可以
            if(begin>end){
                return -1;
            }
//防止越界
            med=begin+(end-begin)/2;
            if(nums[med]==target){
                return med;
            }
            if(nums[med]<target){
                begin=med+1;}
            if(nums[med]>target){
                end=med-1;}
        }
        return -1;
    }
}

力扣34.排序数组中查找元素的第一个和最后一个位置

普通的朴素二分:

假如说是33333,这个例子,我用二分也不清楚他的起始位置和结束位置,还是要往回找,这就和暴力大差不差了

二分本质:二段性

1.查找区间左端点【左边小于t,右边大于t】

细节处理:循环条件,left<right,为什么不是left<=right

首先

class Solution {
    public int[] searchRange(int[] nums, int target) {
    //处理边界情况
    int []ret=new int[2];
    ret[0]=-1;
    ret[1]=-1;
     if(nums.length==0){
         return ret;
     }
    int left=0;
    int right=nums.length-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 ret;
    ret[0]=left;
//二分右端点
//left可以直接从左端点开始
left=right;
right=nums.length-1;
     while(left<right){
    int mid=left+(right-left+1)/2;
    if(nums[mid]<=target){
        left=mid;
    }
    else{
        right=mid-1;
      }
    }
    ret[1]=right;
     return ret;
    }
}

力扣69.x的平方根

这题的本质暴力枚举:

把从1到x的数字平方求一遍,因为有顺序,所以使用二分查找

注意这里细节在于mid*mid假如说是小于,等于的话,

这么画图的原因,我们划分的是要求和放在一起,小于和等于都是我们要求的,所以他们是放在一起

让left变到mid这里,中间数分平方可以落在小于,因为mid平方有可能正好等于x

class Solution {
    public int mySqrt(int x) {
        if(x<1){
            return 0;
        }
     long left=1;
     long right=x;
     while(left<right){
        long  mid=left+(right-left+1)/2;
         if(mid*mid<=x){
           left=mid;
         }else{
             right=mid-1;
         }
     }
     return (int)left;
    }
}

力扣35.搜索插入位置

首先他这个插入位置,我们要发现,假如说不是正好,数组里面没有这个数的话,那么nums的target,比他大的那个值的下标,就是他要插入的下标

方法一:同种思想(这个是来以小于等于为一段,大于为一段的,然后有一个特列,假如说小于等于的情况就是0,不然就是小于等于的下一个

 public static int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while(left<right){
            int mid=left+(right-left+1)/2;
            if(nums[mid]>target){
                right=mid-1;
            }else {
                left=mid;
            }
            if(nums[mid]==target){
                return mid;
            }
        }
        if(nums[0]>=target){
            return 0;
        }
        return left+1;
    }

方法2:以小于和大于等于为两段。(也是需要特殊判定,假如那个target很大,如何处理)

class Solution {
      public static int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-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 left+1;
        }
        return left;
    }
}


相关文章
|
1月前
|
索引
二分查找第二弹
二分查找第二弹
|
2月前
|
算法 C++
c++算法学习笔记 (15) 单调栈与单调队列
c++算法学习笔记 (15) 单调栈与单调队列
|
1月前
前缀和第一弹
前缀和第一弹
|
1月前
|
存储
前缀和第二弹
前缀和第二弹
|
1月前
|
测试技术
深入理解数据结构第二弹——二叉树(2)——堆排序及其时间复杂度
深入理解数据结构第二弹——二叉树(2)——堆排序及其时间复杂度
22 0
|
1月前
|
存储 搜索推荐
深入了解数据结构第四弹——排序(1)——插入排序和希尔排序
深入了解数据结构第四弹——排序(1)——插入排序和希尔排序
16 0
|
1月前
|
搜索推荐
深入理解数据结构第五弹——排序(2)——快速排序
深入理解数据结构第五弹——排序(2)——快速排序
13 0
|
2月前
|
算法 搜索推荐
LeetCode刷题---215. 数组中的第K个最大元素(双指针,快速选择)
LeetCode刷题---215. 数组中的第K个最大元素(双指针,快速选择)
|
11月前
|
索引
【剑指Offer】--->详解二分查找相关练习(二)
【剑指Offer】--->详解二分查找相关练习(二)
56 1
|
11月前
|
存储 搜索推荐 C语言
七个常用的排序算法---快排\归排\希尔\插入\选择\冒泡\堆排(二)
七个常用的排序算法---快排\归排\希尔\插入\选择\冒泡\堆排(二)
47 0