跳转至

剑指 Offer II 061. 和最小的 k 个数对

题目描述

给定两个以升序排列的整数数组 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]

 

提示:

  • 1 <= nums1.length, nums2.length <= 104
  • -109 <= nums1[i], nums2[i] <= 109
  • nums1, nums2 均为升序排列
  • 1 <= k <= 1000

 

注意:本题与主站 373 题相同:https://leetcode.cn/problems/find-k-pairs-with-smallest-sums/

解法

方法一

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution:
    def kSmallestPairs(
        self, nums1: List[int], nums2: List[int], k: int
    ) -> List[List[int]]:
        hp = []
        for x in nums1[:k]:
            for y in nums2[:k]:
                heappush(hp, (-(x + y), [x, y]))
                if len(hp) > k:
                    heappop(hp)
        return [p for _, p in hp]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        Queue<List<Integer>> pq = new PriorityQueue<>(
            (p1, p2) -> { return p2.get(0) + p2.get(1) - (p1.get(0) + p1.get(1)); });
        for (int i = 0; i < nums1.length && i < k; i++) {
            for (int j = 0; j < nums2.length && j < k; j++) {
                pq.offer(List.of(nums1[i], nums2[j]));
                if (pq.size() > k) {
                    pq.poll();
                }
            }
        }
        return new ArrayList<>(pq);
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
    vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
        using pii = pair<int, int>;
        auto cmp = [](pii p1, pii p2) { return p1.first + p1.second < p2.first + p2.second; };
        priority_queue<pii, vector<pii>, decltype(cmp)> pq(cmp);
        for (int i = 0; i < nums1.size() && i < k; ++i) {
            for (int j = 0; j < nums2.size() && j < k; ++j) {
                pq.push({nums1[i], nums2[j]});
                if (pq.size() > k) pq.pop();
            }
        }
        vector<vector<int>> ans;
        while (!pq.empty()) {
            pii p = pq.top();
            pq.pop();
            ans.push_back({p.first, p.second});
        }
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
type pairHeap [][]int

func (a pairHeap) Len() int           { return len(a) }
func (a pairHeap) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a pairHeap) Less(i, j int) bool { return a[i][0]+a[i][1] > a[j][0]+a[j][1] }
func (a *pairHeap) Push(x any)        { *a = append(*a, x.([]int)) }
func (a *pairHeap) Pop() any          { l := len(*a); tmp := (*a)[l-1]; *a = (*a)[:l-1]; return tmp }

func kSmallestPairs(nums1 []int, nums2 []int, k int) [][]int {
    var hp pairHeap
    for _, x := range nums1[:min(k, len(nums1))] {
        for _, y := range nums2[:min(k, len(nums2))] {
            heap.Push(&hp, []int{x, y})
            if len(hp) > k {
                heap.Pop(&hp)
            }
        }
    }
    return hp
}

评论