373. Find K Pairs with Smallest Sums

本文介绍了一种算法问题,即给定两个已排序的整数数组和一个整数k,如何找出这两个数组中组成对的k个最小和。通过两个示例详细说明了解决方案,并提供了两种不同的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值