事件推送问题

一、题目描述

同一个数轴X上有两个点的集合A={A1, A2, ..., Am}和B={B1, B2, ..., Bn},Ai和Bj均为正整数,A、B已经按照从小到大排好序,A、B均不为空,给定一个距离R(正整数),列出同时满足如下条件的所有(Ai, Bj)数对:Ai <= Bj Ai, Bj之间的距离小于等于R 在满足1,2的情况下,每个Ai只需输出距离最近的Bj 输出结果按Ai从小到大的顺序排序。

二、输入输出描述

输入描述

  • 第一行三个正整数m,n,R
  • 第二行m个正整数,表示集合A
  • 第三行n个正整数,表示集合B

输入限制:1<=R<=100000, 1<=n,m<=100000, 1<=Ai,Bj<=1000000000

输出描述

  • 每组数对输出一行Ai和Bj,以空格隔开

三、示例

|----|---------------------------|
| 输入 | 4 5 5 1 5 5 10 1 3 8 8 20 |
| 输出 | 1 1 5 8 5 8 |
| 说明 | |

四、解题思路

  1. 核心思想

通过 "排序 + 双指针" 实现高效的元素匹配:先对setB排序,再用单向移动的指针遍历setB,为setA的每个元素找到满足 "≥valueA 且差值≤r" 的最小setB元素 ------ 核心是 "排序降维复杂度 + 双指针避免重复遍历"。

  1. 问题本质分析
  • 表层问题:在两个数组中匹配满足 "B 元素≥A 元素且差值≤r" 的元素对,每个 A 元素匹配最小的符合条件的 B 元素;
  • 深层问题:
    1. 无序数组的高效匹配:若setB无序,需对每个 A 元素遍历整个 B(时间复杂度 O (m*n)),排序后可通过双指针将复杂度降至 O (m + n log n);
    2. 单向指针的合理性:因setB升序、setA遍历无顺序要求,指针仅需正向移动(已跳过的 B 元素均 < A 当前元素,无需回头)。
  1. 核心逻辑
  • 排序预处理:对setB升序排序,保证元素有序,为双指针单向移动提供基础;
  • 双指针单向遍历:indexB仅正向移动,避免对setB的重复遍历,降低时间开销;
  • 条件筛选:先找到setB中≥valueA 的最小元素,再校验差值是否≤r,保证匹配的是 "最小且符合误差的 B 元素"。
  1. 步骤拆解

  2. 输入读取与初始化

    • 读取setA长度、setB长度、误差范围r
    • 读取setAsetB的所有元素。
  3. 预处理(排序)

    • setB进行升序排序,为双指针匹配做准备。
  4. 双指针匹配

    • 初始化indexB=0(指向setB的起始位置);
    • 遍历setA的每个元素valueA
      1. 移动indexB,直到setB[indexB] ≥ valueA(或indexB越界);
      2. 若未越界且差值≤r,输出元素对;否则跳过。
  5. 结果输出

    • 逐行输出满足条件的元素对,无满足条件的则无输出。

五、代码实现

java 复制代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 读取 m、n、r
        int m = sc.nextInt();
        int n = sc.nextInt();
        int r = sc.nextInt();
        int[] setA = new int[m];
        int[] setB = new int[n];
        // 读取数组 A
        for (int x = 0; x < m; x++) {
            setA[x] = sc.nextInt();
        }
        // 读取数组 B
        for (int y = 0; y < n; y++) {
            setB[y] = sc.nextInt();
        }
        // 调用匹配函数
        matchPairs(setA, setB, r);
    }
    public static void matchPairs(int[] setA, int[] setB, int range) {
        Arrays.sort(setB); // 先对 B 进行排序,确保双指针法可行
        int indexB = 0; // 指向 B 中当前检查的元素
        // 遍历数组 A 中的每个元素
        for (int valueA : setA) {
            // 移动 indexB,使其指向 >= valueA 的最小元素
            while (indexB < setB.length && setB[indexB] < valueA) {
                indexB++;
            }
            // 检查是否满足误差范围
            if (indexB < setB.length && setB[indexB] - valueA <= range) {
                System.out.println(valueA + " " + setB[indexB]);
            }
        }
    }
}
相关推荐
dllxhcjla3 分钟前
数据结构和算法
数据结构
乌萨奇也要立志学C++6 分钟前
【洛谷】BFS 求解最短路:从马的遍历到迷宫问题的实战解析
算法·宽度优先
石去皿10 分钟前
【嵌入式就业6】计算机组成原理与操作系统核心机制:夯实底层基础
c++·面试·嵌入式
老鼠只爱大米15 分钟前
LeetCode经典算法面试题 #46:全排列(回溯、交换、剪枝等五种实现方案详细解析)
算法·leetcode·剪枝·回溯·全排列·stj算法
专注VB编程开发20年16 分钟前
vb.net datatable新增数据时改用数组缓存
java·linux·windows
(>_<)20 分钟前
java minio 分片上传工具类与测试demo
java·minio·分片上传
不想打工的码农20 分钟前
MyBatis-Plus多数据源实战:被DBA追着改配置后,我肝出这份避坑指南(附动态切换源码)
java·后端
Dovis(誓平步青云)29 分钟前
《滑动窗口算法:从 “暴力遍历” 到 “线性高效” 的思维跃迁》
运维·服务器·数据库·算法
Coder_Boy_35 分钟前
Deeplearning4j+ Spring Boot 电商用户复购预测案例
java·人工智能·spring boot·后端·spring
踢足球092943 分钟前
寒假打卡:2026-2-7
java·开发语言·javascript