二分查找、三分查找

二分查找

  • 目标函数具有单调性(单调递增或者递减)
  • 存在上下界( b o u n d e d bounded bounded
  • 能够通过索引访问( i n d e x   a c c e s s i b l e index \ accessible index accessible
int left = 0, right = n - 1;
while (left <= right) {
	int mid = (left + right) / 2;
	if (array[mid] == target) {
		// find the target
		break or return mid;
	} 
	if (array[mid] < target) {
		left = mid + 1;
	} else {
		right = mid - 1;
	}
}
  • l o w e r   b o u n d lower \ bound lower bound
    • 在单调递增数组里 [10, 14, 19, 25, 27, 31, 33, 35, 42, 44],查找第一个 ≥ \geq 31 的数(返回下标),不存在返回 a r r a y . l e n g t h array.length array.length
  • u p p e r   b o u n d upper \ bound upper bound
    • 在单调递增数组里 [10, 14, 19, 25, 27, 31, 33, 35, 42, 44],查找第一个 > > > 26 的数(返回下标),不存在返回 a r r a y . l e n g t h array.length array.length
  • l o w e r   b o u n d lower \ bound lower bound u p p e r   b o u n d upper \ bound upper bound 存在的问题是:给定的 target不一定在数组中存在,array[mid] 即使不等于 target,也可能就是最后的答案,不能随便排除。
  • 二分代码三步走:
    1. 写出二分的条件(一般是一个不等式)。
    2. 把条件放到 i f if if 里,并确定满足条件时要小的( r i g h t = m i d right = mid right=mid)还是要大的( l e f t = m i d left = mid left=mid)。
    3. 另一半放到 e l s e else else 里, l e f t = m i d + 1 left = mid + 1 left=mid+1 r i g h t = m i d − 1 right = mid - 1 right=mid1,如果是后者,求 m i d mid mid 时需要 + 1 1 1。如果题目有无解的情况,上界加 1 1 1 或者下界减 1 1 1,用于表示无解。
// 后继型: 查找第一个 >= target 的数, 不存在返回 n
// 改为 array[mid] > target 就是 upper bound
int left = 0, right = n;
while (left < right) {
	int mid = (left + right) >> 1;
	if (array[mid] >= target) { // 条件满足, 应该被包含
		right = mid;
	} else {
		left = mid + 1;
	}
}
return right;

// 前驱型: 查找第一个 <= target 的数, 不存在返回 -1
int left = -1, right = n - 1;
while (left < right) {
	int mid = (left + right + 1) / 2;
	if (array[mid] <= target) { // 条件满足, 应该被包含
		left = mid;
	} else {
		right = mid - 1;
	}
}
return right;

LeetCode 练习题


三分查找

  • 二分法用于在单调函数上寻找特定值。
    在这里插入图片描述

  • 三分法用于在单峰函数上寻找极大值(或单谷函数上寻找极小值)。

    • 要求函数是分段严格单调递增 / / /递减的(不能出现一段平的情况)。
      在这里插入图片描述
  • 以求单峰函数 f f f 的极大值为例,可在定义域 [ l , r ] [l, r] [l,r] 上取任意两点 l m i d lmid lmid r m i d rmid rmid

    • f ( l m i d ) ≤ f ( r m i d ) f(lmid) \leq f(rmid) f(lmid)f(rmid),则函数必然在 l m i d lmid lmid 处单调递增,极值在 [ l m i d , r ] [lmid, r] [lmid,r] 上。
    • f ( l m i d ) > f ( r m i d ) f(lmid) > f(rmid) f(lmid)>f(rmid),则函数必然在 l m i d lmid lmid 处单调递减,极值在 [ l , r m i d ] [l, rmid] [l,rmid] 上。
    • l m i d lmid lmid 为二等分点, r m i d rmid rmid l m i d lmid lmid 稍加一点偏移量。
      在这里插入图片描述

LeetCode 练习题


  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值