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] 

Credits:
Special thanks to @elmirap and @StefanPochmann for adding this problem and creating all test cases.

给定2个以升序排列的整数数组和1个整数k,从2个数组中各拿出一个数字组成一对,找出k对和最小的数字组合。

解法1:最简单的想法就是暴力brute force解法,但效率肯定不高。

解法2: 最小堆。把所有的点对加入到最小堆,然后输出前k个。但没有利用到“两个数组都有序”这个条件,就算数组无序,也可以利用这个方法。要利用有序这个条件,可以借助mergesort的思路,pair的第一个元素至多包含了nums1数组的前k个元素,k以后的可以不用考虑。所以,这形成了k个list,每一个list都包含了nums2的元素。每一次取所有list中的最小值,然后该list下一个元素入队。

Java:

 public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
List<int[]> r = new ArrayList<>();
if(nums1.length == 0 || nums2.length == 0) return r;
int size = Math.min(nums1.length, k);
int[] index = new int[size];
PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>(){
@Override
public int compare(int[] o1, int[] o2) {
Integer s1 = o1[0] + o1[1];
Integer s2 = o2[0] + o2[1];
return s1.compareTo(s2);
}
});
for(int i = 0; i < size; i++){
queue.add(new int[]{nums1[i], nums2[0], i});
}
int count = 0;
while(!queue.isEmpty()){
int[] pair = queue.poll();
r.add(new int[]{pair[0], pair[1]});
int id = pair[2];
if(++index[id] < nums2.length)
queue.add(new int[]{nums1[id], nums2[index[id]], id});
count++;
if(count == k)
break;
}
return r;
}  

Python:

from heapq import heappush, heappop

class Solution(object):
def kSmallestPairs(self, nums1, nums2, k):
"""
:type nums1: List[int]
:type nums2: List[int]
:type k: int
:rtype: List[List[int]]
"""
pairs = []
if len(nums1) > len(nums2):
tmp = self.kSmallestPairs(nums2, nums1, k)
for pair in tmp:
pairs.append([pair[1], pair[0]])
return pairs min_heap = []
def push(i, j):
if i < len(nums1) and j < len(nums2):
heappush(min_heap, [nums1[i] + nums2[j], i, j]) push(0, 0)
while min_heap and len(pairs) < k:
_, i, j = heappop(min_heap)
pairs.append([nums1[i], nums2[j]])
push(i, j + 1)
if j == 0:
push(i + 1, 0) # at most queue min(n, m) space
return pairs

C++:

// Time:  O(k * log(min(n, m, k))), where n is the size of num1, and m is the size of num2.
// Space: O(min(n, m, k)) class Solution {
public:
vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
vector<pair<int, int>> pairs;
if (nums1.size() > nums2.size()) {
vector<pair<int, int>> tmp = kSmallestPairs(nums2, nums1, k);
for (const auto& pair : tmp) {
pairs.emplace_back(pair.second, pair.first);
}
return pairs;
} using P = pair<int, pair<int, int>>;
priority_queue<P, vector<P>, greater<P>> q;
auto push = [&nums1, &nums2, &q](int i, int j) {
if (i < nums1.size() && j < nums2.size()) {
q.emplace(nums1[i] + nums2[j], make_pair(i, j));
}
}; push(0, 0);
while (!q.empty() && pairs.size() < k) {
auto tmp = q.top(); q.pop();
int i, j;
tie(i, j) = tmp.second;
pairs.emplace_back(nums1[i], nums2[j]);
push(i, j + 1);
if (j == 0) {
push(i + 1, 0); // at most queue min(m, n) space.
}
}
return pairs;
}
};

  

  

All LeetCode Questions List 题目汇总

[LeetCode] 373. Find K Pairs with Smallest Sums 找和最小的K对数字的更多相关文章

  1. [LeetCode] Find K Pairs with Smallest Sums 找和最小的K对数字

    You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...

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

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

  3. 373. Find K Pairs with Smallest Sums 找出求和和最小的k组数

    [抄题]: You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. D ...

  4. 【LeetCode】373. Find K Pairs with Smallest Sums 解题报告(Python)

    [LeetCode]373. Find K Pairs with Smallest Sums 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/p ...

  5. 373. Find K Pairs with Smallest Sums

    You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. 给你两个数组n ...

  6. 373. Find K Pairs with Smallest Sums (java,优先队列)

    题目: You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Def ...

  7. #Leetcode# 373. Find K Pairs with Smallest Sums

    https://leetcode.com/problems/find-k-pairs-with-smallest-sums/ You are given two integer arrays nums ...

  8. Leetcode Find K Pairs with smallest sums

    本题的特点在于两个list nums1和nums2都是已经排序好的.本题如果把所有的(i, j)组合都排序出来,再取其中最小的K个.其实靠后的很多组合根本用不到,所以效率较低,会导致算法超时.为了简便 ...

  9. Find K Pairs with Smallest Sums -- LeetCode

    You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...

随机推荐

  1. 标准C语言(9)

    C语言里所有文字信息必须记录在一组连续的字符类型存储区里所有文字信息必须以字符'\0'做结尾,这个字符的ASCII码就是0符合以上两个特征的内容叫字符串,它们可以用来在程序里记录文字信息.字符串里'\ ...

  2. java8学习之Collector复合与注意事项

    接着上一次[http://www.cnblogs.com/webor2006/p/8318066.html]继续对Collector进行javadoc详读,上一次读到了这: 接下来一条条来过目一下: ...

  3. ffmpeg函数04__v_register_output_format()

    注册复用器,编码器等的函数av_register_all() 注册编解码器avcodec_register_all() 注册复用器的函数是av_register_output_format(). 注册 ...

  4. python 的ConfigParser模块

    Python 之ConfigParser模块 一.ConfigParser简介 ConfigParser 是用来读取配置文件的包.配置文件的格式如下:中括号“[ ]”内包含的为section.sect ...

  5. 29. ClustrixDB 分布式架构/并发控制

    介绍 ClustrixDB使用多版本并发控制(MVCC)和2阶段锁(2PL)的组合来支持混合的读写工作负载.在我们的系统中,读取器享受无锁快照隔离,而写入器使用2PL来管理冲突.并发控制的组合意味着读 ...

  6. 《剑指offer》算法题第三天

    今日题目: 斐波那契数列 青蛙跳台阶问题(及其变种:变态跳台阶) 矩形覆盖 旋转数组的最小数字 矩阵中的路径 机器人的运动范围 细心的同学会发现,第1,2,3题其实对应的是<剑指>书上的同 ...

  7. Makefile样例

    Makefile1 src = $(wildcard ./*cpp) obj = $(patsubst %.cpp, %.o,$(src)) target = test $(target) : $(o ...

  8. unittest详解(三) 测试套件(TestSuite)

    在前面一章中示例了如何编写一个简单的测试,但有两个问题: 我们知道测试用例的执行顺序是根据测试用例名称顺序执行的,在不改变用例名称的情况下,我们怎么来控制用例执行的顺序呢? 一个测试文件,我们直接执行 ...

  9. 为什么要使用 Go 语言,Go 语言的优势在哪里?

    1.Go有什么优势 可直接编译成机器码,不依赖其他库,glibc的版本有一定要求,部署就是扔一个文件上去就完成了. 静态类型语言,但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的 ...

  10. Linux常用命令及操作(第二弹)

    Ctrl l清屏 Ctrl d关闭终端 Ctrl Alt T打开终端 pwd 查看当前的目录 Shift Ctrl C复制 Shift Ctrl V粘贴 Shift Ctrl N打开新的终端 F11 ...