二分----

Posted 萌萌滴太阳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分----相关的知识,希望对你有一定的参考价值。

两种代码模板

代码1

  • 代码1:在循环中查找元素
    适合知道num[mid]等于什么,才能得到结果的情况
public class Solution {
  
    // 「力扣」第 704 题:二分查找
  
    public int search(int[] nums, int target) {
        int len = nums.length;

        int left = 0;
        int right = len - 1;
        // 目标元素可能存在在区间 [left, right]
        //区间还剩一个元素时,继续循环
        while (left <= right) {
            // 推荐的写法是 int mid = left + (right - left) / 2;
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                // 目标元素可能存在在区间 [mid + 1, right]
                left = mid + 1;
            } else {
                // 目标元素可能存在在区间 [left, mid - 1]
                right = mid - 1;
            }
        }
        return -1;
    }
}

代码2

  • 代码2(1):在循环体中排除目标元素一定不存在的区间
    适合 不知道num[mid]等于什么 才能得到结果,但知道什么情况下可以缩小区间,的情况。
    使用 if (nums[mid] < target)判断;
public class Solution {
  
    // 「力扣」第 704 题:二分查找

    public int search(int[] nums, int target) {
        int len = nums.length;

        int left = 0;
        int right = len - 1;
        // 目标元素可能存在在区间 [left, right]
        //区间还剩一个元素时,退出循环
        while (left < right) {
            int mid = left + (right - left) / 2;
            //这里注意使用nums[mid] < target;
            //若使用nums[mid] > target,则mid需要上取整;
            if (nums[mid] < target) {
                // 下一轮搜索区间是 [mid + 1, right]
                left = mid + 1;
            } else {
                // 下一轮搜索区间是 [left, mid]
                right = mid;
            }
        }

        if (nums[left] == target) {
            return left;
        }
        return -1;
    }
}
  • 代码2(2):在循环体中排除目标元素一定不存在的区间

使用if (nums[mid] > target) 判断;会出现left = mid;mid需要上取整:int mid = left + (right - left + 1) / 2;防止死循环

即,出现left = mid情况,mid需向上取整int mid = left + (right - left + 1) / 2;防止死循环。

public class Solution {
  
    // 「力扣」第 704 题:二分查找

    public int search(int[] nums, int target) {
        int len = nums.length;

        int left = 0;
        int right = len - 1;
        while (left < right) {
            int mid = left + (right - left + 1) / 2;
            if (nums[mid] > target) {
                // 下一轮搜索区间是 [left, mid - 1]
                right = mid - 1;
            } else {
                // 下一轮搜索区间是 [mid, right]
                left = mid;
            }
        }

        if (nums[left] == target) {
            return left;
        }
        return -1;
    }
}

思考

二分的思想是,通过num[mid]与一个target对比,来缩小区间,

  • 当给定target时,自然与target比较;
  • 当未给定target时,找那些和mid比较 能产生缩小区间效果的元素,如:左右边界常作为target,

有重复元素的情况

针对有重复的情况,是将下面两种**无重复情况**下的划分:
nums[l] <= nums[mid]
nums[l] > nums[mid])
改为下面三种划分,将等于的情况单独提取出来,【适合重复情况】
nums[l] < nums[mid]
nums[l] == nums[mid] //若nums[l]不是目标值,因为相等,所以可以缩小一个范围,即l++;
nums[l] > nums[mid])

在有序数组中进行查找一个数(二分下标)

在整数范围内查找一个整数(二分答案)

山峰数组

arr[mid] 与 arr[mid + 1]比较

以上是关于二分----的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数