LeetCode——373.查找和最小的K对数字

1,252 阅读2分钟

题目:

给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k。 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2。 找到和最小的 k 对数字 (u1,v1), (u2,v2) ... (uk,vk)。

示例1

输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
输出: [1,2],[1,4],[1,6]
解释: 返回序列中的前 3 对数:
     [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]

示例2

输入: nums1 = [1,1,2], nums2 = [1,2,3], k = 2
输出: [1,1],[1,1]
解释: 返回序列中的前 2 对数:
     [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]

示例3

输入: nums1 = [1,2], nums2 = [3], k = 3 
输出: [1,3],[2,3]
解释: 也可能序列中所有的数对都被返回:[1,3],[2,3]

思路:

考虑题目的特殊性,两个数组都是升序,利用小根堆,维护一个容量为k的小根堆,堆内的每个元素是arr[],其内都有两个数。

Java

package leetcodeTest;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;

public class S373_kSmallestPairs_new {
    public ArrayList<ArrayList<Integer>> kSmallestPairs(int[] num1, int[] num2, int k){
        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
        //创建一个小根堆
        PriorityQueue<int[]> pQ = new PriorityQueue<int[]>(k, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return twoSum(o2)- twoSum(o1);
            }
        });
        int pre_n1 = 0x7fffffff;
        int pre_n2 = 0x7fffffff;
        for (int n1: num1)
            for (int n2: num2){
                if (n1 > pre_n1 && n2 > pre_n2)
                    break;
                int[] arr = new int[]{n1, n2};
                if (pQ.size() < k)
                    pQ.add(arr);
                else if (pQ.size() >=k && twoSum(arr)< twoSum(pQ.peek())){
                    pQ.poll();
                    pQ.add(arr);
                    pre_n1 = n1;
                    pre_n2 = n2;
                }
            }
        while (!pQ.isEmpty()){
            ArrayList<Integer> list = new ArrayList<Integer>();
            int[] arr = pQ.poll();
            list.add(arr[0]);
            list.add(arr[1]);
            res.add(list);
        }
        return res;
    }
    public int twoSum(int[] arr){
        return arr[0]+arr[1];
    }
    public static void main(String[] args){
        S373_kSmallestPairs_new s373 = new S373_kSmallestPairs_new();
        int[] num1 = {1,7,11};
        int[] num2 = {2,4,6};
        System.out.println(s373.kSmallestPairs(num1, num2, 3));
    }
}