二分:寻找有序数列第一个满足某条件的元素的位置

这篇博客探讨了如何在有序递增序列中找到第一个大于等于或大于给定值x的元素的位置。通过二分查找算法,分别解决了两个问题:1) 寻找第一个大于等于x的元素的位置,2) 寻找第一个大于x的元素的位置。文章详细解释了查询情况、代码实现,并强调了在二分查找过程中的一些关键点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

有这样的问题:如果递增序列 A 中的元素可能重复,那么如何对给定的欲查询元素x,求出序列中第一个大于等于x的元素的位置L以及第一个大于x 的元素的位置R。

序列中第一个大于等于x的元素的位置

先看第一问

例如对下标从0开始、有5个元素的序列 {1,3,3,3,6}来说,如果要查询 3,则应当得到 L=1、R=4;如果查询 5,则应当得到L=R=4;如果查询 6,则应当得到 L=4、R=5;而如果查询8,则应当得到L=R=5。

显然,如果序列中没有x,那么L和R也可以理解为假设序列中存在x,则x应当在的位置。

那么既然 L和R 可能会等于 5,那也就是说 R 的起始值不是 4,而是 5,这是因为二分法返回的范围只能是 L到R 的区间,如果初始 R 为 4,那如果没有查询到的话,只能返回 4,就不会出现查询 8 返回 L=R=5 的情况了

查询情况

假设存在序列 A,当前二分区间为 [left,right](left为0, right为数组长度)

  • 如果 A[mid] >= x,说明第一个大于等于 x 的元素的位置一定在 mid 处或者 mid 的左侧,应该往左子区间[left,mid]继续查询,即令 right = mid
    在这里插入图片描述

  • 如果 A[mid] < x,说明第一个大于等于 x 的元素的位置一定在 mid 的右侧,应该往右子区间 [mid + 1,right] 继续查询,即令 left= mid + 1

在这里插入图片描述

如图很容易写出代码

代码

// A[] 为递增序列,x 为欲查询的数,函数返回第一个大于等于 x 的元素的位置
// 二分上下界为左闭右闭[left, right],传入的初始值为 [0, n]
public static int lower_bound(int[] A, int left, int right, int x) {
   
   
    int mid; // mid 为  left 和  right 的中点
    whi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值