题目重点:OA 问两数值差最小且原始下标间距至少 distance;边扫描边维护可配对历史值,避免按数值排序丢下标。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版输出最小绝对差 |a[i]−a[j]|,要求 i<j 且 j−i≥k;题目可能要求 pair 或值,必须按现场接口改。
- k≥1,n<k+1 时没有合法 pair,训练版返回 None;重复值允许,差可为 0。
- 如果有多个最优 pair,不做特定 tie-break;若原题要求索引,需额外保存有序值与索引。
解题路线
- 先用 O(n²) 参考解枚举所有 i<j、j−i≥k,作为正确性 oracle 与小规模测试。
- 从 j=k 开始扫描,每步把 a[j−k] 加入支持重复的有序 multiset,此时集合恰包含所有 i≤j−k 的候选值。
- 在集合中找 a[j] 的前驱和后继;有序数轴上离查询值最近者必为二者之一,更新最小差。用平衡树可 O(log n) 每步;Python 无内建树时可用坐标压缩+Fenwick/有序容器。
- 若只看数值排序后的邻居而不维护原下标,可能选出距离不足 k 的 pair;先保证下标资格,再比较数值。
- 测试 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 怎么存?
- 流式输入且内存受限如何近似?
- 动态更新数组元素时怎样维护答案?
