面试经典150题 P373 查找和最小的K对数字
时间轴
2025-12-08
init
题目:
这题不能用双指针,因为不是线性的,用堆解决的核心是先把 {nums1[0],nums2[j]} 都放入堆中(0 <= j <= nums2.size()),然后从堆中去除最小和的那一对{i,j}, j 不变的情况下比它大的值中{i+1, j}最小。
那为什么可以让 j 不变呢?因为 j 的推进(即 j+1)已经在初始化阶段全部加入堆({num1[0], nums2[j]})
示例 1 的 nums1 = [1, 7, 11],nums2 = [2, 4, 6]。我们把每个数对的和算出来,可以得到一个矩阵 $ M $,其中 $ M_{i,j} = nums1[i] + nums2[j] $。
$$
M = \begin{bmatrix} 3 & 5 & 7 \ 9 & 11 & 13 \ 13 & 15 & 17 \end{bmatrix}
$$
由于 nums2 是递增的,所以矩阵每一行都是递增的。问题相当于: 合并 $ n $ 个升序列表,找前 $ k $ 小元素。(其中 $ n $ 是 nums1 的长度) 根据 P23 合并 K 个升序链表 的堆的做法:
- 把矩阵每一行的第一个数 $ M_{i,0} $ 及其位置 $ (i, 0) $ 加到最小堆中。
- 循环 $ k $ 次。
- 每次循环,弹出堆顶,把堆顶 $ M*{i,j} $ 的对应数对加入答案,把堆顶右边元素 $ M*{i,j+1} $ 及其位置 $ (i, j+1) $ 入堆。
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 常想一二,不思八九!
评论