2020暑假算法复习(1)——二分

本文主要内容:

  • 手动实现二分(手动档
  • 用lower_bound与upper_bound函数实现二分(自动档

1 二分

  • 功能:
    1.较短时间内在有序序列中查找某个数
    2.寻找一段区间中具有不同性质的两端子区间的边界
  • 时间复杂度:
    o(logn)
  • 主要思路:
    1.双指针算法
    2.l和r指针分别指向区间两端,求l和r的中点mid,若mid指向满足左区间性质,则l = mid,r = mid - 1,否则r = mid, l = mid + 1, 根据l的取值确定mid的计算公式(是否需要加1)
  • 注意事项:
    1.浮点数二分时因为l和r是浮点型变量,所以注意浮点数的相等判断
    2.特别特别要注意边界问题
  • 经典例题:
    1.整数二分:AcWing 789. 数的范围
    2.浮点数二分:AcWing 790. 数的三次方根
    拓展习题:
    1.二分答案+验证:Acwing102.最佳牛围栏、 Acwing1227. 分巧克力

1.1 寻找二分区间左子区间的右端点

while(l < r)
{
	int mid = l + r + 1 >> 1;
	if(check_left(mid))l = mid;//check()函数根据题意来写
	else r = mid – 1;
}	//循环结束时l和r指向左子区间右端点,若左子区间不存在则l和r指向区间左端点

1.2 寻找二分区间右子区间的左端点

while(l < r)
{
	int mid = l + r >> 1;
	if(check_right(mid))r = mid;
	else l = mid + 1;
}	//循环结束时l和r指向右子区间右端点,若右子区间不存在则l和r指向二分区间右端点

2 用lower_bound与upper_bound函数实现二分(无须导入其他头文件)

  • 在从小到大的排序数组中:
  1. lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。
  2. upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。

  • 在从大到小的排序数组中,重载lower_bound()和upper_bound():
  1. lower_bound( begin,end,num,greater<数组类型>() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字。
  2. upper_bound( begin,end,num,greater<数组类型>() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字。

你可能感兴趣的:(2020暑假算法学习总结)