373. Find K Pairs with Smallest Sums
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]
含义:给定两个升序的数组,各抽取一个求和,给出和最小的k对组合
方法一:
1 public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) { 2 int len1=nums1.length; 3 int len2=nums2.length; 4 List<int[]> res=new ArrayList<int[]>(); 5 if (len1 == 0 || len2 == 0 || k == 0) { 6 return res; 7 } 8 Queue<int[]> queue = new PriorityQueue<int[]>(len1*len2, 9 new Comparator<int[]>() { 10 @Override 11 public int compare(int[] a, int[] b) { 12 return a[0]+a[1] - b[0]-b[1]; 13 } 14 });//由头到尾,节点值升序排列 15 for(int i=0;i<nums1.length;i++){ 16 for(int j=0;j<nums2.length;j++){ 17 int[] s=new int[]{nums1[i],nums2[j]}; 18 queue.add(s); 19 } 20 } 21 k = Math.min(k,queue.size()); 22 while(k>0){ 23 res.add(queue.poll()); 24 k--; 25 } 26 return res; 27 }
方法二:
1 public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) { 2 PriorityQueue<int[]> que = new PriorityQueue<>((a, b) -> a[0] + a[1] - b[0] - b[1]); //由头到尾,节点值升序排列 3 List<int[]> res = new ArrayList<>(); 4 if (nums1.length == 0 || nums2.length == 0 || k == 0) return res; 5 for (int i = 0; i < nums1.length && i < k; i++) que.offer(new int[]{nums1[i], nums2[0], 0}); //最后一个0表示选取了nums2中位置0的数 6 while (k-- > 0 && !que.isEmpty()) { 7 int[] cur = que.poll(); 8 res.add(new int[]{cur[0], cur[1]}); 9 if (cur[2] == nums2.length - 1) continue;//cur[2] 表示选取了nums2中位置cur[2]的数,达到数组右边界了,所以continue 10 que.offer(new int[]{cur[0], nums2[cur[2] + 1], cur[2] + 1});//nums1中的当前值和nums2中位置cur[2]+1的数构成新的组合加入优先队列中 11 } 12 return res; 13 }