基本思想
首先确定答案在一个区间当中L到R。
通过中点判断答案在区间的某一边。
区间缩小,再次找中点。
70%的二分题目和单调性有关系
95%的题目 存在一种两段性的性质,左边成立,右边不成立。通过这个两段性的性质划分区间。
模板一
最后答案在右区间的左端点。
算mid下取整。
while(l<r){
int mid = l+r>>1;
if(check(mid))
r=mid;
else
l=mid+1;
}
return l;
模板二
最后的答案在左区间的右端点。
算mid上取整(避免死循环)
while(l<r){
int mid = l+r+1>>1;
if(check(mid)
l=mid;
else
r=mid-1;
}
return l;
流程
- 确定二分的边界l,r。定左右区间。
- 编写二分的代码框架。
- 设计一个check性质,性质要保证答案一定在性质的左右边界处且情况唯一。如果结果在左区间右端点用模板二,如果结果在右区间左端点用模板一
- 判断区间如何更新
- 如果更新方式写的是l=mid,r=mid-1,就在算mid的时候加一。
例 leetcode 69 X的平方根
按照二分流程分析
- 确定二分的边界,答案一定在0-x之间。
- 编写二分的代码框架
- check性质确定是。mid<=x/mid (防止溢出) 答案为左区间右端点,用模板二。
- 判断区间边界的情况,当条件满足时,mid包含在结果区间中。
- 更新情况是l=mid,r=mid-1。避免死循环,计算mid时要加一上取整。
public int mySqrt(int x) {
int l=0,r=x;
while(l<r){
int mid= (l+r+1)>>1;
if(mid<=x/mid){
l=mid;
}else
r=mid-1;
}
return l;
}
例 leetcode 35 搜索插入位置
这里使用二分模板三
public int searchInsert(int[] nums, int target) {
int start=0;
int end = nums.length-1;
if(target<nums[0])