一、前言
二分的题目最令人困扰的是两个方面:
- 不知道什么时候用二分解决
- 边界条件难以处理
本文着重解决这两个问题,并提供一些题目用于练习。
二、什么时候用二分解决
举一个简单的例子,也是最终转化的模型
已知
- f(x)= {10, 11, 13, 17, 22, 42, 59}
- maxValue = 24.86
求f(x)<= maxValue 的x最大值
这个模型有两个特点:
- 给出的条件: f(x)是单调的
- 想要得到的结果: 求以某值为界限的最大值或最小值
有这两个特点的题目就可以用二分法解决
三、如何处理边界条件
求小于等于目标值target的最大下标x
private boolean judge(int [] arr, int pos, int target) {
if (arr[pos] <= target) {
return true;
} else {
return false;
}
}
public int solve(int [] arr,int target) {
// 区间为左闭右开[left,right)
int left = 0;int right = arr.length;
while(left < right) {
// 取中间值,防int溢出
int mid = left + (right - left)/2;
// 判断mid位置是否为target对应下标的左侧
if (judge(arr,mid,target)){
left = mid + 1;
} else {
right = mid;
}
}
// 判断left是否还是在target下标的左侧,这种情况为target对应下标超出右边界,left的值为数组右边界(7),可能需要做处理
if (left == arr.length) {
// todo
}
// left为大于target的最小值
return left - 1;
}
上图为target对应下标超出右边界情况