当前位置: 面试刷题>> 查找和最小的 K 对数字(经典算法150题)


### 题目描述 给定两个已排序的整数数组 `nums1` 和 `nums2`,以及一个整数 `k`,要求找出和最小的 `k` 对数字对 `(i, j)`,其中 `i` 是 `nums1` 的索引,`j` 是 `nums2` 的索引。每对 `(i, j)` 形成的数字对值为 `nums1[i] + nums2[j]`。 ### 示例 假设 `nums1 = [1, 7, 11]`,`nums2 = [2, 4, 6]`,`k = 3`,则和最小的 3 对数字对为 `(1, 2)`,`(1, 4)`,`(1, 6)`,它们的和分别为 `3`,`5`,`7`。 ### 解题思路 这个问题可以使用最小堆(优先队列)来解决。我们可以将每对数字对的和以及它们的索引作为元素放入最小堆中,每次从堆中取出和最小的元素,然后更新堆。具体步骤如下: 1. 初始化一个最小堆,堆中的元素包含数字对的和、`nums1` 的索引和 `nums2` 的索引。 2. 将第一对 `(nums1[0], nums2[0])` 及其和加入堆中。 3. 重复以下步骤 `k` 次: - 从堆中取出和最小的元素(包括和、两个索引)。 - 将这对数字对的结果输出或存储。 - 如果 `nums1` 或 `nums2` 的索引还可以继续增加(即未到达数组末尾),则将新的数字对(通过增加索引)及其和加入堆中。 ### PHP 示例代码 ```php class Pair { public $sum; public $i; public $j; function __construct($sum, $i, $j) { $this->sum = $sum; $this->i = $i; $this->j = $j; } } function findKthSmallestPairs($nums1, $nums2, $k) { $result = []; $heap = new SplPriorityQueue(); $heap->insert(new Pair($nums1[0] + $nums2[0], 0, 0), -$nums1[0] - $nums2[0]); // 使用负值保证是最小堆 while (!$heap->isEmpty() && count($result) < $k) { $pair = $heap->extract(); $result[] = [$nums1[$pair->i], $nums2[$pair->j]]; if ($pair->i + 1 < count($nums1)) { $heap->insert(new Pair($nums1[$pair->i + 1] + $nums2[$pair->j], $pair->i + 1, $pair->j), -$nums1[$pair->i + 1] - $nums2[$pair->j]); } if ($pair->j + 1 < count($nums2)) { $heap->insert(new Pair($nums1[$pair->i] + $nums2[$pair->j + 1], $pair->i, $pair->j + 1), -$nums1[$pair->i] - $nums2[$pair->j + 1]); } } return $result; } // 示例用法 $nums1 = [1, 7, 11]; $nums2 = [2, 4, 6]; $k = 3; print_r(findKthSmallestPairs($nums1, $nums2, $k)); ``` ### Python 示例代码 ```python import heapq def findKthSmallestPairs(nums1, nums2, k): heap = [] result = [] if not nums1 or not nums2 or k <= 0: return result heapq.heappush(heap, (nums1[0] + nums2[0], 0, 0)) while heap and len(result) < k: _, i, j = heapq.heappop(heap) result.append((nums1[i], nums2[j])) if i + 1 < len(nums1): heapq.heappush(heap, (nums1[i + 1] + nums2[j], i + 1, j)) if j + 1 < len(nums2): heapq.heappush(heap, (nums1[i] + nums2[j + 1], i, j + 1)) return result # 示例用法 nums1 = [1, 7, 11] nums2 = [2, 4, 6] k = 3 print(findKthSmallestPairs(nums1, nums2, k)) ``` ### JavaScript 示例代码 ```javascript class Pair { constructor(sum, i, j) { this.sum = sum; this.i = i; this.j = j; } } function findKthSmallestPairs(nums1, nums2, k) { const result = []; const heap = []; if (!nums1.length || !nums2.length || k <= 0) return result; heap.push(new Pair(nums1[0] + nums2[0], 0, 0)); heap.sort((a, b) => a.sum - b.sum); while (heap.length && result.length < k) { const [pair] = heap.splice(0, 1); result.push([nums1[pair.i], nums2[pair.j]]); if (pair.i + 1 < nums1.length) { heap.push(new Pair(nums1[pair.i + 1] + nums2[pair.j], pair.i + 1, pair.j)); heap.sort((a, b) => a.sum - b.sum); } if (pair.j + 1 < nums2.length) { heap.push(new Pair(nums1[pair.i] + nums2[pair.j + 1], pair.i, pair.j + 1)); heap.sort((a, b) => a.sum - b.sum); } } return result; } // 示例用法 const nums1 = [1, 7, 11]; const nums2 = [2, 4, 6]; const k = 3; console.log(findKthSmallestPairs(nums1, nums2, k)); ``` 以上代码均实现了查找和最小的 `k` 对数字对的功能,并给出了 PHP、Python 和 JavaScript 的示例实现。
推荐面试题