一.整数二分
1.关于二分的单调性
A.二分的本质不是单调性,满足单调性一定可以二分,不满足单调性也可以二分
B.二分的本质是寻找某种性质的分界点。
C.只要可以找到某种性质,使得区间的前半部分满足,后半部分不满足,那么就可以用二分把这个分界点找到
2.二分查找的模版
//模版一
public static int binsearch_left(int nums[],int target)
{
int l=0;
int r=nums.length-1;
while(l<r)
{
int mid=(l+r)>>1;
if(check(mid))
r=mid;
else
l=mid+1;
}
//若返回-1,则是target对应index的后面的值
return nums[l]==target? l:-1;
}
//模版二
public static int binsearch_right(int nums[],int target)
{
int l=0;
int r=nums.length-1;
while(l<r)
{
int mid=(l+r+1)>>1;
if(check(mid))
l=mid;
else
r=mid-1;
}
return nums[r]==target? r:-1;
}
A.划分成[l,mid]还是[l,mid-1]的标准是什么?
?区间的划分是根据r和l的移动来定的
结果在左区间&&mid值可能为结果,那么l=mid && r=mid-1,那么划分成[l,mid] [mid+1,r]
结果在右区间&&mid值可能为结果,那么r=mid && l=mid+1那么划分成[l,mid-1] [mid ,r]
acwing789
B.l和r怎样移动的问题
C.关于为什么在模版二中要写成 mid=(l+r)>>1;
目的是防止死循环,造成死循环是因为JAVA采用的是下取整
当l=r-1时, mid=(l+r)>>1=l,再更新l=mid,所以l还是等于r-1,陷入了死循环
D.二分一定是有解的,题目可能无解
由于if判断条件是‘<=’或’>=’,不等号和等于号是‘或’的关系,所以就算没有等于目标值,对于
'>='而言是大于目标值的下一个,对于‘<=’而言是小于目标中的上一个.有的时候会出现超过nums.length-1,需要特判 leetcode35
3.二分查找的应用
A. acwing 15
B.acwing 22,要看yxc的解释的图示
利用的两条性质
某种性质的分界点是nums[0],比nums[0]大单调增,比nums[0]小的单调减;现在只要是比nums[0]大就下标右移,反之下标左移,最终就是分界点
C.acwing789,这道题可以帮助理解A问题
二.浮点数二分
A.浮点数的二分不存在上下取整的问题,所以不需要处理边界
B.要求小数点后k位,那么精度是k+2
public static double binSearch(Double target)
{
double l=-100;
double r=100;
while((r-l)>1e-8)//精度
{
double mid=(l+r)/2;
if(mid*mid*mid<=target)
l=mid;
else
r=mid;
}
return l;
}