### 整数对最小和问题解决方案
#### 背景分析
该问题是典型的贪心算法应用案例,目标是从两个数组 `array1` 和 `array2` 中分别选取若干对元素,使这些配对的和尽可能小。通过合理排序与优先队列的选择策略可以有效降低时间复杂度。
---
#### 方法概述
一种高效的解决方法是基于 **堆(Heap)数据结构** 的实现方式。具体思路如下:
1. 将其中一个数组按升序排列。
2. 使用一个小顶堆来存储当前可能的最小和及其对应的索引位置。
3. 每次从堆中弹出最小值,并将其扩展到下一个候选值,直到找到所需的前 K 个最小和为止。
此方法的时间复杂度为 \( O(K \log n) \),相较于暴力枚举法显著优化[^2]。
以下是具体的代码实现示例:
---
#### Python 实现
```python
import heapq
def find_k_smallest_pairs(array1, array2, k):
result = []
if not array1 or not array2:
return result
heap = [(array1[0] + array2[0], 0, 0)] # 初始化堆 (sum, i, j)
visited = set((0, 0))
while len(result) < k and heap:
sum_val, i, j = heapq.heappop(heap)
result.append([array1[i], array2[j]])
# 扩展新的候选项
if i + 1 < len(array1) and (i + 1, j) not in visited:
heapq.heappush(heap, (array1[i + 1] + array2[j], i + 1, j))
visited.add((i + 1, j))
if j + 1 < len(array2) and (i, j + 1) not in visited:
heapq.heappush(heap, (array1[i] + array2[j + 1], i, j + 1))
visited.add((i, j + 1))
return result
# 测试用例
if __name__ == "__main__":
array1 = [1, 7, 11]
array2 = [2, 4, 6]
k = 3
pairs = find_k_smallest_pairs(array1, array2, k)
total_sum = sum(a + b for a, b in pairs)
print(f"最小和的 {k} 对元素为: {pairs}")
print(f"总和为: {total_sum}")
```
上述代码实现了利用堆求解最小和的方法。对于给定测试用例 `[1, 7, 11]`, `[2, 4, 6]` 和 `k=3`,程序会返回前三对最小和的组合并计算其总和[^1]。
---
#### Java 实现
```java
import java.util.*;
public class SmallestSumPairs {
public static List<List<Integer>> findKSmallestPairs(int[] nums1, int[] nums2, int k) {
PriorityQueue<int[]> minHeap = new PriorityQueue<>((a, b) -> (a[0] - b[0]));
List<List<Integer>> result = new ArrayList<>();
if (nums1.length == 0 || nums2.length == 0 || k == 0) {
return result;
}
Set<String> visited = new HashSet<>();
minHeap.offer(new int[]{nums1[0] + nums2[0], 0, 0});
visited.add("0,0");
while (!minHeap.isEmpty() && result.size() < k) {
int[] current = minHeap.poll();
int sum = current[0];
int i = current[1];
int j = current[2];
result.add(Arrays.asList(nums1[i], nums2[j]));
if (i + 1 < nums1.length && !visited.contains((i + 1) + "," + j)) {
minHeap.offer(new int[]{nums1[i + 1] + nums2[j], i + 1, j});
visited.add((i + 1) + "," + j);
}
if (j + 1 < nums2.length && !visited.contains(i + "," + (j + 1))) {
minHeap.offer(new int[]{nums1[i] + nums2[j + 1], i, j + 1});
visited.add(i + "," + (j + 1));
}
}
return result;
}
public static void main(String[] args) {
int[] nums1 = {1, 7, 11};
int[] nums2 = {2, 4, 6};
int k = 3;
List<List<Integer>> pairs = findKSmallestPairs(nums1, nums2, k);
System.out.println("最小和的 " + k + " 对元素为:");
for (List<Integer> pair : pairs) {
System.out.println(pair.get(0) + ", " + pair.get(1));
}
}
}
```
以上展示了如何在 Java 中使用优先队列解决问题[^3]。
---
#### 时间复杂度分析
- 堆操作每次插入/删除的时间复杂度为 \( O(\log m) \),其中 \( m \) 是堆中的节点数量。
- 总体上最多执行 \( O(k \cdot \log (\min(n_1, n_2)))\) 次操作,因此效率较高。
---
#### 结果验证
针对样例输入:
```
array1 = [1, 1, 2, 3]
array2 = [1, 2, 3]
k = 2
```
输出应为:
```
[[1, 1], [1, 1]]
总和为:4
```
这表明所选方法能够正确处理此类问题。
---