二分查找算法模板

☆* o(≧▽≦)o *☆嗨~我是小奥🍹
📄📄📄个人博客:小奥的博客
📄📄📄优快云:个人优快云
📙📙📙Github:传送门
📅📅📅面经分享(牛客主页):传送门
🍹文章作者技术和水平有限,如果文中出现错误,希望大家多多指正!
📜 如果觉得内容还不错,欢迎点赞收藏关注哟! ❤️

二分查找

二分搜索的三种写法

// 左闭右闭区间,求 >=x 的第一个数 
// >x 可以转换成 >= (x+1)
// <x 可以转换成 (>=x) -1
// <=x 可以转换成 (>x)-1,即 >=(x+1) - 1
int binarySearch(int[] nums, int target) {
    int l = 0, r = nums.length - 1; // 左闭右闭区间 [0, r]
    while(l <= r) {
        int mid = l + (r - l) >> 1;
        if(nums[mid] < target) {
            l = mid + 1; //[mid + 1, right]
        } else {
            r = mid - 1; //[l, mid - 1]
        }
    }
    return l; // l == r + 1
}
// 左闭右开区间
int binarySeach(int[] nums, int target) {
    int l = 0, r = nums.length; // 左闭右开区间 [l, r)
    while(l < r) {
        int mid = l + (r - l) >> 1;
        if(nums[mid] < target) {
            l = mid + 1; // [mid + 1, r)
        } else {
            r = mid; // [l, mid)
        }
    }
    return l; //  l == r
}
// 左开右开区间
int binarySearch(int[] nums, int target) {
    int l = -1, r = nums.length; // 开区间 (-1, r)
    while(l + 1 < r) {
        int mid = l + (r - l) >> 1;
        if(nums[mid] < target) {
            l = mid; // (mid, r)
        } else {
            r = mid; // (l, mid)
        }
    }
    return r; // l + 1 = r
}

二分搜索,左边界和右边界

// 搜索左边界
int left_bound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] == target) {
            // 别返回,锁定左侧边界
            right = mid - 1;
        }
    }
    // 判断 target 是否存在于 nums 中
    // 此时 target 比所有数都大,返回 -1
    if (left == nums.length) return -1;
    // 判断一下 nums[left] 是不是 target
    return nums[left] == target ? left : -1;
}
// 搜索右边界
int right_bound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] == target) {
            // 别返回,锁定右侧边界
            left = mid + 1;
        }
    }
    // 此时 left - 1 索引越界
    if (left - 1 < 0) return -1;
    // 判断一下 nums[right] 是不是 target
    return nums[right] == target ? right : -1;
}

练习题

二分答案

🚀 875. 爱吃香蕉的珂珂

🚀 2187. 完成旅途的最少时间

🚀 2226. 每个小孩最多能分到多少糖果

最小化最大值

🚀 2439. 最小化数组中的最大值

🚀 2513. 最小化两个数组中的最大值

🚀

最大化最小值

🚀 1552. 两球之间的磁力

🚀 2517. 礼盒的最大甜蜜度

🚀 2528. 最大化城市的最小供电站数目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值