(Binary Search)二分查找的学习笔记&边界问题&模板


前言

二分查找很常用,属于 “一看就会,一写就错” 的类型。在网上看了很多博客视频,记录一下心得。(大雪菜tql)


一、什么时候用到二分查找?

不是有序性 ,而是二段性
二段性是指存在一个分界点,能把代求解区域分成两段在这里插入图片描述

二、怎么使用二分查找?

1.测试代码

代码如下(示例):

	    public static void binarySearch(int[] data, int k) {
	        System.out.println("加*代表常用,剩余的作为对比。");
	        int l = 0, r = data.length - 1;
	        while (l < r) {
	            int mid = (l + r) / 2;
	            if (data[mid] >= k)
	                r = mid;
	            else
	                l = mid + 1;
	        }
	        System.out.println("*大于等于:" + k + " 下标:" + l + " 值:" + data[l]);
	        
	        l = 0;
	        r = data.length - 1;
	        while (l < r) {
	            int mid = (l + r + 1) / 2;
	            if (data[mid] >= k)
	                r = mid - 1;
	            else
	                l = mid;
	        }
	        System.out.println(" 小于:" + k + " 下标:" + l + " 值:" + data[l]);
	        
	        l = 0;
	        r = data.length - 1;
	        while (l < r) {
	            int mid = (l + r + 1) / 2;
	            if (data[mid] <= k)
	                l = mid;
	            else
	                r = mid - 1;
	        }
	        System.out.println("*小于等于:" + k + " 下标:" + l + " 值:" + data[l]);
	        
	        l = 0;
	        r = data.length - 1;
	        while (l < r) {
	            int mid = (l + r) / 2;
	            if (data[mid] <= k)
	                l = mid + 1;
	            else
	                r = mid;
	        }
	        System.out.println(" 大于:" + k + " 下标:" + l + " 值:" + data[l]);
	    }
	
	    public static void main(String[] args) {
	        int[] data = {2, 5, 8, 13, 15, 15, 15, 15, 15, 15, 20};
	        binarySearch(data, 15);
	    }

2.思考&结论

可以看到,主要的不同点有三处

		r = mid; l = mid + 1;
		--------------------
		l = mid; r = mid - 1;
		--------------------
		mid = (l + r) / 2; mid = (l + r + 1) / 2;

其中mid的不同,在于选择向下还是向上取整。
取整不同的原因是:避免进入死循环
如果向下取整, l = m i d ; r = m i d − 1 ; l = mid; r = mid - 1; l=mid;r=mid1; 在边界上会进入死循环,所以针对这种选择,使用向上取整
l 和 r 的移动,有着不同的含义,可参考代码理解。有两种加*的表示常用的写法,可做为模板使用。

        while (l < r) {
            int mid = (l + r + 1) / 2;
            if (data[mid] <= k)
                l = mid;
            else
                r = mid - 1;
        }//左部分的右边界
        while (l < r) {
            int mid = (l + r) / 2;
            if (data[mid] >= k)
                r = mid;
            else
                l = mid + 1;
        }//右部分的左边界

总结

在这里插入图片描述

推荐几道力扣题
找左边的右边界: 33、34、69、74、275、5751
找右边的左边界: 33、34、35、74、153、278、1482
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值