题目:
373. 查找和最小的 K 对数字 - 力扣(LeetCode)
解题思路:
分析题目:
- 和最小的 => 优先考虑到排序,升序排序k次即可
- 两个数组各取一个数,将其和进行排序 => 多路归并
具体逻辑:
通过优先队列来模拟堆,将两个数组各取一个数的和来作为优先级,保存这两个数的索引(a,b)
=> PriorityQueue<int[]> priorityQueue = new PriorityQueue<>();
同时在优先队列中设置比较器(a,b)->(nums1[a[0] + nums2[a[1]] - nums1[b[0] + nums2[b[1]])
最后按照多路归并的思路,不断添加一个新的最小和
代码如下:
class Solution {
public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
int n = nums1.length, m = nums2.length;
List<List<Integer>> result = new ArrayList<>();
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> (nums1[a[0]] + nums2[a[1]]) - (nums1[b[0]] + nums2[b[1]]));
//存入nums1数组的每个数字和nums2的0下标数据和
for (int i = 0; i < Math.min(n, k); i++) {
pq.offer(new int[]{i, 0});
}
while (k > 0 && !pq.isEmpty()) {
int[] pair = pq.poll();
int num1Index = pair[0];
int num2Index = pair[1];
List<Integer> pairList = new ArrayList<>();
pairList.add(nums1[num1Index]);
pairList.add(nums2[num2Index]);
result.add(pairList);
// 如果 nums2 中还有更多的元素,则添加下一个可能的对到队列中
if (num2Index + 1 < m) {
pq.offer(new int[]{num1Index, num2Index + 1});
}
k--;
}
return result;
}
}