-
确定一个区间,使得目标值一定在区间中。
-
找一个性质,满足可以使区间一分为二。
- 性质具有二段性。
- 答案是二段性的分界点。
-
小心越界left + ((right - left) >> 1)
-
利用好TreeSet 添加与查找都是Ologn 免写二分
//TreeSet是有序的Set集合 treeSet.ceiling(X); //直接找大于X的第一个数 找不到返回null treeSet.floor(X);//找小于X的第一个数 //其余和普通Set一样。 //不要用int来接,否则无法判别null。
-
整数二分 防止死循环。
-
//一定要看答案在哪个范围里面,再选择模板。 while(L<R) //第一种 mid = (L+R+1)>>1 if(check(mid)) L = M; //就看这个。 else R = M-1; return L; //-----------------------------check后面写的模板来判断用哪个模板 while(L<R) //第二种 M = (L+R)>>1 if(check(mid)) R = M; else L = M +1; //就看这个。 return L; //---------------------2个模板都得记,按写的check来。
1.二分难就难在这个check() 函数。
2.模板只需要要背 L = M 算mid+1 / L = M+1 算mid不加1; -
例题:数的范围
-
找左端点:大于等于x的第一个位置。
while(l<r){ //找左端点 int mid = l+r>>1; //用什么模板看 下面一句。 if(A[mid] >= x) r = mid; else l = mid+1; } ansl = l;
-
找右端点:小于等于x 的分界点。
-
范围(左端点,n-1)
-
//找右端点 while(l<r){ int mid = l+r+1>>1; if(A[mid]<=x) l = mid; else r=mid-1; } ansr = r;
-
-
-
浮点数二分 就不用考虑死循环了,直接R=mid L = mid。