LeetCode #373 Find K Pairs with Smallest Sums 查找和最小的K对数字

373 Find K Pairs with Smallest Sums 查找和最小的K对数字

Description:
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:

Example 1:

Input: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
Output: [[1,2],[1,4],[1,6]]
Explanation: 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:

Input: nums1 = [1,1,2], nums2 = [1,2,3], k = 2
Output: [1,1],[1,1]
Explanation: 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:

Input: nums1 = [1,2], nums2 = [3], k = 3
Output: [1,3],[2,3]
Explanation: All possible pairs are returned from the sequence: [1,3],[2,3]

题目描述:
给定两个以升序排列的整形数组 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个一般使用堆
使用小顶堆, 固定 nums1中的数, 找到 nums2中的数加入结果中
时间复杂度O((k + n)lgn), 空间复杂度O(n)

代码:
C++:

class Solution 
{
public:
    vector> kSmallestPairs(vector& nums1, vector& nums2, int k) 
    {
        vector> result;
        if (nums1.empty() or nums2.empty()) return result;
        int n = nums1.size(), m = nums2.size();
        k = min(n * m, k);
        priority_queue>> heap;
        for (int i = 0; i < n; i++) heap.push({-nums1[i] - nums2[0], {i, 0}});
        while (result.size() < k) 
        {
            auto cur = heap.top();
            heap.pop();
            int i = cur.second.first, j = cur.second.second;
            result.push_back({nums1[i], nums2[j++]});
            if (j < m) heap.push({-nums1[i] - nums2[j], {i, j}});
        }
        return result;
    }
};

Java:

class Solution {
    public List> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        PriorityQueue queue = new PriorityQueue<>((o1, o2) -> compare(o2, o1));
        for (int i : nums1) {
            if (queue.size() == k && compare(queue.peek(), new int[]{i, nums2[0]}) < 0) break;
            for (int j : nums2) {
                int[] arr = new int[]{i, j};
                if (queue.size() < k) queue.offer(arr);
                else if (!queue.isEmpty() && compare(queue.peek(), arr) > 0) {
                    queue.poll();
                    queue.offer(arr);
                } else break;
            }
        }
        List> result = new ArrayList<>();
        while (!queue.isEmpty()) {
            int[] cur = queue.poll();
            result.add(0, Arrays.asList(cur[0], cur[1]));
        }
        return result;
    }
    
    private int compare(int[] arr1, int[] arr2) {
        return (arr1[0] + arr1[1]) - (arr2[0] + arr2[1]);
    }
}

Python:

class Solution:
    def kSmallestPairs(self, nums1: List[int], nums2: List[int], k: int) -> List[List[int]]:
        return map(list, heapq.nsmallest(k, itertools.product(nums1, nums2), key=sum))

你可能感兴趣的:(LeetCode #373 Find K Pairs with Smallest Sums 查找和最小的K对数字)