You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于双变量键的二分查找:有序数对数组的最小符合元素查询

嘿,这个问题确实可以用二分查找来高效解决,核心是利用数组已有的排序特性(x升序,同x下y升序)来减少不必要的遍历。我来给你拆解具体步骤和实现思路:

核心思路

我们要找的是满足c>a且d>b的最小数对,这里的“最小”定义是:先比较x,x越小越优先;x相同则y越小越优先。基于数组的排序特性,我们可以分两步走:

  1. 先定位到所有x>a的数对范围;
  2. 在这些数对中,找到x最小的组,再在该组里找最小的y>b;如果当前x组没有满足条件的y,就继续找下一个更大的x组,直到找到为止。

具体实现步骤

1. 预处理分组(可选但推荐)

因为原数组已经按x升序、同x下y升序排列,我们可以先把数组按x分组,每个组内的y列表天然是升序的,这样后续二分查找y会更方便:

# 示例输入数组
pairs = [(2,3),(2,4),(3,2),(3,4),(3,5)]

# 预处理:按x分组,存储每个x对应的y列表
x_to_ys = {}
sorted_x = []
for x, y in pairs:
    if x not in x_to_ys:
        x_to_ys[x] = []
        sorted_x.append(x)
    x_to_ys[x].append(y)

这里sorted_x是严格升序的不同x值列表,x_to_ys则存储每个x对应的y升序列表。

2. 用二分查找定位目标x范围

我们需要找到第一个大于a的x的位置,这可以用bisect模块的bisect_right方法:

import bisect

a, b = 2, 3
# 找到第一个x > a的索引
x_idx = bisect.bisect_right(sorted_x, a)

bisect_right会返回插入a后不破坏sorted_x升序的位置,也就是第一个大于a的x的索引。

3. 在目标x组中找最小的y>b

从x_idx开始遍历每个x组,对每个组的y列表用二分查找找第一个大于b的y:

result = None
while x_idx < len(sorted_x):
    current_x = sorted_x[x_idx]
    ys = x_to_ys[current_x]
    # 找到第一个y > b的索引
    y_idx = bisect.bisect_right(ys, b)
    if y_idx < len(ys):
        # 找到满足条件的最小y
        result = (current_x, ys[y_idx])
        break  # 因为x是升序的,第一个满足的就是最小的数对,直接退出
    x_idx += 1

# 输出结果
print(result)  # 对于a=2,b=3,输出(3,4)

为什么这个方法高效?

  • 定位x范围用了O(log N)的二分查找(N是不同x的数量);
  • 每个x组内找y用了O(log M)的二分查找(M是该x组的y数量);
  • 一旦找到第一个满足条件的x组和y,就可以直接返回,不需要遍历后续元素,最坏情况下才会遍历所有x组,但实际中通常很快就能找到。

特殊情况处理

  • 如果没有任何数对满足c>a且d>b,result会是None,你可以根据需求返回提示信息;
  • 如果a比所有x都大,同样返回None;
  • 如果某个x组的所有y都<=b,就跳过该组,继续检查下一个更大的x组。

内容的提问来源于stack exchange,提问作者Vedant Dixit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:21:11