二分算法和板子

​1.2.1 二分算法可以解决的问题​二分的本质是临界点,给定某个区间,在区间上定义了某种性质,使得整个区间一分为二,一般区间满足性质,另一半不满足性质,那么二分可以寻找性质的边界,既可以寻找左边界,也可以寻找右边界。​二分不仅限于有序序列的查找,但有序序列是最常见的一种情况。​arr = [3, 27, 15, 48, 90, 6, 2, 17, 54, 11]​在arr这个序列中,6是临界点,6左边的数(包括6)都能被3整除,6右边的数都不能被3整除;2也是临界点,2左边
摘要由CSDN通过智能技术生成

1.2.1 二分算法可以解决的问题

二分的本质是临界点,给定某个区间,在区间上定义了某种性质,使得整个区间一分为二,一般区间满足性质,另一半不满足性质,那么二分可以寻找性质的边界,既可以寻找左边界,也可以寻找右边界。

二分不仅限于有序序列的查找,但有序序列是最常见的一种情况。

arr = [3, 27, 15, 48, 90, 6, 2, 17, 54, 11]

在arr这个序列中,6是临界点,6左边的数(包括6)都能被3整除,6右边的数都不能被3整除;2也是临界点,2左边的数都能被3整除,2右边的数(包括2)都能不被3整除,二分算法就可以把6和2这两个数查找出来。

1.2.2 二分算法库函数

C++

algorithm头文件下:

  • 查找是否存在:binary_search(first, last, value);

存在返回true,不存在返回false,因为不能返回元素具体位置所以用的很少。

  • 查找首个大于value的元素的迭代器:std::upper_bound(first, last, value)

返回指向范围 [first, last) 中首个大于 value 的元素的迭代器,或若找不到这种元素则返回 last,数组返回该位置的指针。

  • 查找首个大于等于value的元素的迭代器:std::lower_bound(first, last, value)

返回指向范围 [first, last) 中首个大于等于 value 的元素的迭代器,或若找不到这种元素则返回 last,数组返回该位置的指针。

Java

数组:Arrays.binarySearch(Object[] a, Object key)方法

Python

bisect标准库:

  • bisect.bisect(array, value):返回一个位置 pos,如果把 value 插入到 pos 位置的话,那么 pos 左边的所有元素都**小于等于 value,右边的所有元素都大于 **value

  • bisect.bisect_left(array, value):返回一个位置 pos,如果把 value 插入到 pos 位置的话,那么 pos 左边的所有元素都**小于 value,右边的所有元素都大于等于 **value

  • bisect.bisect_left(array, value):类似bisect.bisect(array, value)

bisect标准库的bisect()类方法都是查找合适的插入位置,bisect标准库还提供了insort()类方法在查找到的合适插入位置插入指定的 value 值。

1.2.3 朴素二分:查找指定元素位置

每一次都比较当前区间中点是否满足某个条件,以查找递增序列的整数x为例,当区间中点为x时,返回中点下标,当区间中点大于x时,向区间左半边查找,当区间中点小于x时,向右半边查找,如果迭代结束还没有找到,则返回-1。

二分算法的高效性在于每一步都可以去除当前区间中的一半元素,时间复杂度是 O ( l o g n ) O(logn) O(logn)

C++

int biSearch(int l, int r, int x) {
   
	while (l <= r) {
   
		int mid = l + r >> 1;
		if (nums[mid] == x)	return mid;
		else if (nums[mid] > x)	r = mid - 1;
		else	l = mid + 1;
	}
	return -1;
}

1.2.4 lower:ans是绿色区间的左端点

记区间左、右端点分别为left和right,区间中点为mid,要查找的答案为ans,ans把区间分成左右两部分,左区间为红色区间,右区间为绿色区间,模板一:ans是绿色区间的右端点,这类问题被记为lower类型,C++的algorithm实现了该算法,即 std::lower_bound()
在这里插入图片描述

(1)当mid落在绿色区间时,ans一定在mid左边,而且有可能恰好是mid,即ans在区间[left, mid]里;
在这里插入图片描述

(2)当mid落在红色区间时,ans一定在mid右边且不包含mid,即ans在区间 [mid + 1, ri

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值