事件推送问题

一、题目描述

同一个数轴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;
    • 读取setA和setB的所有元素。
  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]);
            }
        }
    }
}
相关推荐
非优秀程序员2 小时前
第05章 播放器大战,暴风、快播与那一夜|《互联网产品恩仇录》
算法
非优秀程序员2 小时前
第04章 邮箱大战,163 与 QQ 的暗战|《互联网产品恩仇录》
java·vue.js·架构
知已难寻2 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
文丑颜不良啊4 小时前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang5 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪6 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息6 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼6 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff8 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈