基础算法-二分-C++实现

二分-C++实现

算法基本思想和步骤:
1、根据题目确定分界规则(即确定二分的分界点)
2、判断区间中点是否符合分界规则,根据不同情况缩小区间
3、处理边界问题(整数二分)


二分:整数二分、浮点数二分

二分的思想,对于一个有序排列的数组a[N] ,看作区间 [ l, r ],根据题目条件可以将其划分为两部分,将要查找的那个点 x 设为分界点,对于分界的条件,要使只有分界点一边的区间符合这个条件,另一边的区间完全不符合这个条件(如一边 <x,另一边 >=x,包不包含分界点取决于题目),然后判断区间中点(即a[mid])是否符合条件,最后就是缩小区间,如果 mid 在 x 左边,则说明要找的分界点x 一定在右半边区间内(即[mid,r]),这时就可以把 l 换成 mid 再继续判断(即l = mid),同理,如果 mid 在 x 右边,则说明要找的分界点 x 一定在左半边区间内(即[l,mid]),那就把 r 换成 mid再判断(即r = mid)(这里如果是整数二分,缩小后的区间包不包含 mid 需要注意分界点条件,因为有可能mid 就是要找的分界点,如果是浮点数二分就不用)


整数二分记模板快速技巧:
1.求左边界:mid在x右边就是r = mid,在左边就是l = mid + 1,mid = (l + r) / 2
2.求右边界:mid在x左边就是l = mid,在右边就是r = mid - 1,mid = (l + r + 1) / 2(为什么要加一后面第一道例题有解释)

浮点数二分:mid = (l + r) / 2,mid在x左边就是l = mid,mid在x右边就是r = mid


AcWing题库-789-数的范围

题目
给定一个按照升序排列的长度为n的整数数组,以及 q 个查询。

对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。

如果数组中不存在该元素,则返回“-1 -1”。

输入格式
第一行包含整数n和q,表示数组长度和询问个数。

第二行包含n个整数(均在1~10000范围内),表示完整数组。

接下来q行,每行包含一个整数k,表示一个询问元素。

输出格式
共q行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回“-1 -1”。

数据范围
1≤n≤100000
1≤q≤10000
1≤k≤10000
输入样例:
6 3
1 2 2 3 3 4
3
4
5
输出样例:
3 4
5 5
-1 -1


思路解析:
此题是整数二分,找到某个元素 x 的起始和终止位置,那么找起始位置的时候分界点条件就可以设为a[mid] >= x,即分界点的右半边都要满足这个条件,也就是说我们要找的是左边界(始终记得要找答案的是分界点),判断a[mid]是否满足条件时,如果满足,即 >=x,说明 x 在 mid 左边或者就是mid,那就要让缩小的区间包含mid,即r = mid。如果不满足,即 <x,说明 x 在 mid 右边且跟mid绝对不重合,那缩小的区间就不用包含mid,即l = mid + 1。同理,找终止位置的时候分界点条件可以设为a[mid] <= x,即分界点的左半边都要满足这个条件,也就是说我们要找的是右边界,判断a[mid]是否满足条件时,如果满足,说明x在mid右边或者就是mid,缩小的区间需要包含mid,即l = mid。如果不满足,说明x在mid左边且不等于mid,缩小的区间不包含mid,即r = mid - 1


需要注意的是,找右边界的时候mid = (l + r + 1) / 2,因为整数除法向下取整,如果l =

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值