You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.
Define a pair (u,v) which consists of one element from the first array and one element from the second array.
Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.
Example 1:
Given nums1 = [1,7,11], nums2 = [2,4,6], k = 3 Return: [1,2],[1,4],[1,6] The first 3 pairs are returned from the sequence: [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
Example 2:
Given nums1 = [1,1,2], nums2 = [1,2,3], k = 2 Return: [1,1],[1,1] The first 2 pairs are returned from the sequence: [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
Example 3:
Given nums1 = [1,2], nums2 = [3], k = 3 Return: [1,3],[2,3] All possible pairs are returned from the sequence: [1,3],[2,3]解法一:用数组int[nums1.length] idx保存nums1中每个元素在nums2中匹配的元素下标,每次遍历nums1中所有元素找一个最小的和,找k次,所以复杂度O(k*n), n 为nums1和nums2中较短的长度。
public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
k = Math.min(k,nums1.length*nums2.length);
List<int[]> result = new ArrayList<>(k);
if(k==0) return result;
int[] idx = new int[nums1.length];
for(;k>0;k--){
int min = Integer.MAX_VALUE;
int t=0;
for(int i=0; i<nums1.length; i++){
//如果idx[i]>=nums2.length,则nums1[i]已经和nums2中所有元素都匹配过了,所以跳过i.
if(idx[i]<nums2.length && min>nums1[i]+nums2[idx[i]]){
min = nums1[i]+nums2[idx[i]];
t = i;
}
}
if(t>=0){
int[] temp = new int[2]; temp[0] = nums1[t]; temp[1]=nums2[idx[t]];
result.add(temp);
idx[t]++;
}
}
return result;
}
解法二: Use Java Priority Queue to create a Max heap with size k. check all n1*n2 pairs and update the max heap (if current pair sum is smaller than heap top, remove top, and insert current pair), in the end all pairs in the heap will be the smallest k pairs.
public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
k = Math.min(k,nums1.length*nums2.length);
if(k==0) return new ArrayList<int[]>();
//initiate size should be bigger than 0
PriorityQueue<int[]> heap = new PriorityQueue<>(k, new Comparator<int[]>(){
//need max heap, top is the max, so reverse i and j
public int compare(int[] j, int[] i) {
return (i[0] + i[1] -(j[0] + j[1]));
}
});
for(int i=0; i<nums1.length; i++){
for(int j=0; j<nums2.length;j++){
if(heap.size()<k){
heap.add(new int[]{nums1[i],nums2[j]});
}
else{
if(heap.peek()[0]+heap.peek()[1] > nums1[i]+nums2[j]){
heap.remove();
heap.add(new int[]{nums1[i],nums2[j]});
}
}
}
}
return new ArrayList<>(heap);
}