二分查找第一弹

简介: 二分查找第一弹

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;
    }
}


相关文章
|
6月前
|
索引
二分查找第二弹
二分查找第二弹
|
6月前
位运算第一弹
位运算第一弹
|
6月前
|
机器学习/深度学习 搜索推荐 算法
【洛谷 P1177】【模板】快速排序 题解(快速排序+指针)
**快速排序模板题解** - **任务**:对输入的N个整数进行排序。 - **算法**:使用快速排序,避免使用C++的STL`sort`。 - **输入**:一行包含N(N≤10^5),第二行是N个不超过10^9的整数。 - **输出**:排序后的整数序列,空格分隔。 - **样例**:输入`5 4 2 4 5 1`,输出`1 2 4 4 5`。 - **提示**:20%的数据,N≤10^3;所有数据,N≤10^5。 - **代码**:定义`partition`函数划分数组,主函数`main`读取数据,调用`quickSort`排序,然后打印结果。
22 0
|
7月前
leetcode代码记录(三数之和
leetcode代码记录(三数之和
33 1
|
6月前
位运算第三弹
位运算第三弹
|
6月前
|
存储
位运算第二弹
位运算第二弹
|
6月前
|
测试技术
深入理解数据结构第二弹——二叉树(2)——堆排序及其时间复杂度
深入理解数据结构第二弹——二叉树(2)——堆排序及其时间复杂度
74 0
|
7月前
leetcode代码记录(有序数组两数之和
leetcode代码记录(有序数组两数之和
44 0
|
7月前
leetcode代码记录(二分查找
leetcode代码记录(二分查找
28 0
|
7月前
leetcode代码记录(不同的二叉搜索树
leetcode代码记录(不同的二叉搜索树
29 0

热门文章

最新文章