题目描述:
给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k。
定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2。
找到和最小的 k 对数字 (u1,v1), (u2,v2) … (uk,vk)。
思路:
思路(这里我们采用建堆的方式解决):
- 建立一个大小为 k 的大顶堆(如果求最大k对则建小顶堆)
- 把数对放到优先队列里,堆顶为最大数组
- 若取下一对数组比较 比堆顶小则入堆 这样结束后堆中即是最小k对数组
代码实现
public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
if(nums1.length == 0 || nums2.length == 0){
return new ArrayList<>();
}
PriorityQueue<int[]> pq = new PriorityQueue<>(k,new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return getSum(o2) - getSum(o1);
}
});
for(int i = 0;i < nums1.length;i++){
for(int j = 0;j < nums2.length;j++){
int[] tmp = new int[]{nums1[i],nums2[j]};
if(pq.size() < k){
pq.add(tmp);
}else{
if(getSum(tmp) < getSum(pq.peek())){
pq.poll();
pq.add(tmp);
}
}
}
}
List<List<Integer>> res = new ArrayList<>();
while(!pq.isEmpty()){
int[] poll = pq.poll();
res.add(Arrays.asList(poll[0],poll[1]));
}
return res;
}
public int getSum(int[] o){
return o[0] + o[1];
}