二分查找

简介: 二分查找

二分查找的前提


网络异常,图片无法展示
|


使用递归实现二分查找


public static <E extends Comparable<E>> int search(E[] arr, E target) {
        return search(arr, 0, arr.length - 1, target);
    }
    private static <E extends Comparable<E>> int search(E[] arr, int l, int r, E target) {
        if(l > r) {
            return -1;
        }
        int mid = l + (r - l) / 2;
        if(arr[mid].compareTo(target) == 0) { // 刚好找到中间的位置
            return mid;
        }else if (arr[mid].compareTo(target) > 0) { // 查找mid前面的元素
            return search(arr, l, mid - 1, target);
        }else { //(arr[mid].compareTo(target) < 0)
            return search(arr, mid + 1, r, target);
        }
    }


使用非递归实现二分查找


private static <E extends Comparable<E>> int search1(E[] arr, E target) {
        int l = 0, r = arr.length - 1;
        while(l <= r) { // 数组中存在元素时
            int mid = l + ( r - l) / 2;
            if(arr[mid].compareTo(target) == 0) { // 刚好中间的元素就是
                return mid;
            }
            if(arr[mid].compareTo(target) > 0) { // 中间的元素小于target,接着查找右边的列表
                r = mid - 1;
            }else { // 中间的元素大于target, 接着查找左边的列表
                l = mid + 1;
            }
        }
        return -1;
    }


二分查找法的变种


查找大于target的最小值


  • 当未查找到这样的元素,那么将返回数组长度。


  • 当中间值大于等于目标值,那么查询返回下一边界需要加上上一次的中间值,所以r = mid


网络异常,图片无法展示
|


/**
 * 查找大于target的最小值
 * @param arr
 * @param target
 */
public static <E extends Comparable<E>> int upper(E[] arr, E target) {
    int l = 0, r = arr.length;
    while(l < r) {
        int mid = l + (r - l) / 2;
        if(arr[mid].compareTo(target) == 0) {
            return mid + 1;
        }else if(arr[mid].compareTo(target) > 0) { // 这个r = mid是因为mid的位置可能是目标值
            r = mid;
        }else {
            l = mid + 1;
        }
    }
    // l和r最后都都指向同一个位置。没找到则返回arr.length
    return l;
}


查找目标元素最大的下标元素 ceil


  • 如果有等于target的元素就返回最大的下标元素。


  • 如果没有等于target的元素,那么就返回大于target的最小元素。即上面实现的upper函数。


网络异常,图片无法展示
|


public static <E extends Comparable<E>> int ceil(E[] arr, E target) {
        int index = upper(arr, target);
        if(arr[index - 1].compareTo(target) == 0) {
            return index - 1;
        }
        return index;
    }


查找目标元素最小的小标元素 lower_ceil


  • 如果有等于target的元素就返回最小的下标元素。


  • 如果没有等于target的元素,那么就返回大于target的最小元素。即上面实现的upper函数。


网络异常,图片无法展示
|


查找小于target的最大值


网络异常,图片无法展示
|


按照上面的逻辑写成的程序会出现死循环


网络异常,图片无法展示
|


网络异常,图片无法展示
|


LeetCode相关习题


LeetCode 875


网络异常,图片无法展示
|


/**
     * 使用二分法,解决leetCode875
     * @param piles
     * @return
     */
    public static int leetCode875(int[] piles, int h) {
        // 假设他先吃二分法中间的那个根数
        int l = 1; // 最少吃一根
        int r = Arrays.stream(piles).max().getAsInt(); // 假设吃数组中最大数量的根数
        while(l < r) {
            int mid = l + (r - l) / 2;
            if(eatingTime(piles, mid) <= h) { // 此时mid可能会目标值
                r = mid;
            }else {
                l = mid + 1;
            }
        }
        return l;
    }
    public static int eatingTime(int[] arr, int k) {
        int res = 0;
        for(int pile: arr) {
            res = res + pile / k + (pile % k > 0 ? 1 : 0);
        }
        return res;
    }


LeetCode 1011


网络异常,图片无法展示
|


相关文章
|
4月前
|
前端开发 JavaScript
医院报告单p图软件,诊断报告p图, 在线制作仿真病历【js框架】
完整的仿真病历生成系统。以下是使用HTML、CSS和JavaScript实现的完整代码,包含表单输入、样式设计和病历生成功能
|
7月前
|
机器学习/深度学习 人工智能 缓存
MHA2MLA:0.3%数据微调!复旦团队开源推理加速神器,KV缓存狂降96.87%
MHA2MLA是复旦大学、华东师范大学、上海AI Lab等机构联合推出的数据高效微调方法,通过引入多头潜在注意力机制(MLA),显著优化基于Transformer的LLM推理效率,降低推理成本。
241 1
MHA2MLA:0.3%数据微调!复旦团队开源推理加速神器,KV缓存狂降96.87%
|
安全 前端开发 测试技术
SystemVerilog学习-01-系统验证概述(一)
SystemVerilog学习-01-系统验证概述
497 0
SystemVerilog学习-01-系统验证概述(一)
|
容器
react-Ant Design框架项目中文字轮播与图片轮播的实现
在react-Ant Design框架项目中实现文字轮播和图片轮播,在这里记录一下,实现过程有一点小坑需要注意
779 0
react-Ant Design框架项目中文字轮播与图片轮播的实现
|
C++
Ubuntu16.04安装VS code图文教程
Ubuntu16.04安装VS code图文教程
424 0
Ubuntu16.04安装VS code图文教程
|
Java 定位技术 Android开发
Android Studio获取开发版SHA1值和发布版SHA1值的史上最详细方法
今天我想把百度地图的定位集成到项目中来,想写个小小的案例,实现一下,但在集成百度地图时首先要申请秘钥,申请秘钥要用到SHA1值,所以今天就来总结一下怎样去获取这个值吧,希望对大家有帮助。
Android Studio获取开发版SHA1值和发布版SHA1值的史上最详细方法
|
Java Linux 虚拟化
Java 大后端各种架构图汇总(建议收藏!!)(3)
Java 大后端各种架构图汇总(建议收藏!!)(3)
582 0
Java 大后端各种架构图汇总(建议收藏!!)(3)
|
SQL 机器学习/深度学习 存储
什么是spark?通俗易懂,一文读懂
什么是spark?通俗易懂,一文读懂
702 0
什么是spark?通俗易懂,一文读懂