通过率 38% · 提交 807 · 通过 308
小慕正在处理一个上的两个项目集合A = {A1, A2, …, Am}和B = {B1, B2, …, Bn},其中Ai和Bj均为正整数,且两个集合已经按照从小到大的顺序排好序。 A和B均不为空,给定一个R(正整数),小慕需要列出所有同时满足如下条件的(Ai, Bj)数对: 1. Ai <= Bj 2. Ai与Bj之间的距离小于等于R 3. 在满足条件1和2的前提下,每个Ai只需输出 4. 输出结果按照Ai从小到大的顺序排序
这类题属于华为 OD 机考真题方向中「100分 / 双指针」方向的高频题型,通常考察对「100分 / 双指针」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
第一行三个正整数m,n,R 第二行m个正整数,表示集合A 第三行n个正整数,表示集合B 输入限制: 1 <= R <= 100000,1 <= n, m <= 100000,1 <= Ai, Bj <= 1000000000
每组数对输出一行Ai和Bj,以空格隔开
示例 1
输入示例
4 5 5 1 5 5 10 1 3 8 8 20
输出示例
1 1 5 8 5 8
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
首先我们考虑单个 A[i] 的情况。 要找到 A[i] 中距离最近的 B[j],换句话说就是在数组 B 中找到下一个恰好大于等于 A[i] 的数 B[j],且两者之间的差值 B[j] - A[i] 要小于等于 R。
要找到在 B 数组中下一个恰好大于等于 A[i] 的数,这个过程非常简单。 由于 B 数组已经进行了从小到大的排序,这个过程可以用如下的代码来完成:
如果写成 while 循环,则为:
单个 A[i] 的情况非常简单,我们可以通过一次遍历数组 B 来找到对应的 B[j]。
由于 A 数组也是已经排好序的,我们容易得到以下结论: 在 A 数组中,假设存在两个元素 A1 和 A2,其中 A1 的位置在 A2 前面(也就是有 A1 <= A2),它们对应的 B 中的元素分别是 B1 和 B2,那么 B1 的位置一定不会位于 B2 后面(也就是有 B1 <= B2)。
更进一步的结论是,假设我们已知 A1 在 B 数组中对应的数组是 B1,而 A2 是 A1 在 A 中的下一个元素,那么要找到 A2 中对应的 B2,不用在 B 数组中从头找起,而是直接从 B1 继续往后寻找即可。
那么,我们就可以用两个指针 i 和 j,来分别作为 A 和 B 数组的索引。 在对某个 A[i] 找到对应的 B[j] 之后,由于 A[i+1] 在 B 中对应的元素索引必然大于等于 j,因此我们率先令 i 向前移动一步(即 i += 1),再在数组 B 中继续向前移动 j,直到找到第一个大于等于当前 A[i] 的值。
对应的代码为:
这样我们就用双指针完成了这道题目。
当然,此处关于 i 的循环,由于每次只前进一步,需要对所有的 i 都考虑其对应的 j,因此外层的 while 循环改为 for 循环也是可以的。
复杂度分析 设数组 A 的长度为 n,数组 B 的长度为 m(题面保证两数组各自已按从小到大排好序)。
总时间复杂度为 O(n + m),空间复杂度为 O(n + m) 用于存放两个输入数组;若不计输入本身,额外空间只有两个指针变量,为 O(1)。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有