SWE · CodeSignal OA

Capital One 下标隔至少 K 的最接近数值 Pair

OA 问两数值差最小且原始下标间距至少 distance;边扫描边维护可配对历史值,避免按数值排序丢下标。

题目重点:OA 问两数值差最小且原始下标间距至少 distance;边扫描边维护可配对历史值,避免按数值排序丢下标。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版输出最小绝对差 |a[i]−a[j]|,要求 i<j 且 j−i≥k;题目可能要求 pair 或值,必须按现场接口改。
  • k≥1,n<k+1 时没有合法 pair,训练版返回 None;重复值允许,差可为 0。
  • 如果有多个最优 pair,不做特定 tie-break;若原题要求索引,需额外保存有序值与索引。

解题路线

  1. 先用 O(n²) 参考解枚举所有 i<j、j−i≥k,作为正确性 oracle 与小规模测试。
  2. 从 j=k 开始扫描,每步把 a[j−k] 加入支持重复的有序 multiset,此时集合恰包含所有 i≤j−k 的候选值。
  3. 在集合中找 a[j] 的前驱和后继;有序数轴上离查询值最近者必为二者之一,更新最小差。用平衡树可 O(log n) 每步;Python 无内建树时可用坐标压缩+Fenwick/有序容器。
  4. 若只看数值排序后的邻居而不维护原下标,可能选出距离不足 k 的 pair;先保证下标资格,再比较数值。
  5. 测试 k=1、k=n−1、重复值、负数、无合法 pair、所有值相等以及最优值来自相距很远的索引。

手动走一遍

训练 a=[5,1,4,5],k=2:j=2 时可配 a[0]=5,与 4 差 1;j=3 时可配 a[0]=5、a[1]=1,与 5 的最近差 0,答案 0(索引 0 与 3)。

规模与取舍

n 个元素,平衡树插入/前驱/后继各 O(log n),总 O(n log n) 时间、O(n) 空间;暴力 oracle O(n²) 时间、O(1) 额外空间。若值域小可用计数/Fenwick 变体。

易错点与追问

容易失分的边界

  • 按值排序后只看相邻元素,忽略原始索引距离。
  • 集合只保留最近一个合法下标,却可能漏更早且更近的数值。
  • 用 set 丢重复值,虽然差 0 的判定可能幸存,但若要返回 pair/删除会错。
  • k≥n 时访问空集合。

继续深挖

  • 若要返回字典序最小最优索引 pair 怎么存?
  • 流式输入且内存受限如何近似?
  • 动态更新数组元素时怎样维护答案?
✓已复制微信号!