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 = [,,], nums2 = [,,],  k = 

Return: [,],[,],[,]

The first  pairs are returned from the sequence:
[,],[,],[,],[,],[,],[,],[,],[,],[,]

Example 2:

Given nums1 = [,,], nums2 = [,,],  k = 

Return: [,],[,]

The first  pairs are returned from the sequence:
[,],[,],[,],[,],[,],[,],[,],[,],[,]

Example 3:

Given nums1 = [,], nums2 = [],  k =  

Return: [,],[,]

All possible pairs are returned from the sequence:
[,],[,]

思路:这个题目需要转化一下。我们构建一个二维矩阵matrix,matrix[i][j]=nums1[i] + nums2[j]。

例如:对于nums1=[1, 7, 11], nums2=[2, 4, 6],矩阵matrix是这样子:

   +------------
|
|
|

因为nums1和nums2都是有序的,因此matrix里每一行都是从小到大,每一列也是从小到大。

那么这个题就变成了,在这个矩阵中找前k小的数。我们用最小堆可以解决这个问题。

首先,左上角的matrix[0][0]肯定是最小的。我们将它放入堆中,作为seed。

之后,我们对这个堆做K次操作:

  • 从堆顶取出最小的数,判断它在矩阵中的行和列(可以用tuple实现),将对应的nums1和nums2的两个数构造成pair添加进结果。
  • 若取出的数不在矩阵最后一列,则将该行它的下一个数放入堆中。
  • 若取出的数在矩阵第一列,且不在最后一行,则还要将它的下一行行首的数放入堆中。
  • 若堆为空,则提前退出循环(没有这么多pair)。

算法复杂度: K次循环,每次循环从堆中取出一个数,最多放入两个数,则堆空间最大为O(K), push和pop操作复杂度为O(logK)。总时间复杂度为O(KlogK)。

代码心得:tuple类型声明往往比较长,可以用typedef。

 class Solution {
public:
vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
vector<pair<int, int> > res;
if (!nums1.size() || !nums2.size()) return res; typedef tuple<int, int, int> triInt;
vector<triInt> heap(, make_tuple(nums1[] + nums2[], , ));
int height = nums1.size(), width = nums2.size();
while (k-- && heap.size()) {
triInt top = heap.front();
std::pop_heap(heap.begin(), heap.end(), greater<triInt>()); heap.pop_back();
int row = get<>(top), col = get<>(top);
res.push_back(make_pair(nums1[row], nums2[col]));
if (col < width - ) {
heap.push_back(make_tuple(nums1[row] + nums2[col + ], row, col + ));
std::push_heap(heap.begin(), heap.end(), greater<triInt>());
}
if (col == && row < height - ) {
heap.push_back(make_tuple(nums1[row + ] + nums2[col], row + , col));
std::push_heap(heap.begin(), heap.end(), greater<triInt>());
}
}
return res;
}
};

Find K Pairs with Smallest Sums -- LeetCode的更多相关文章

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

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

  2. [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 ...

  3. #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 ...

  4. [LeetCode] 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. Define ...

  5. Leetcode Find K Pairs with smallest sums

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

  6. 【leetcode】Find K Pairs with Smallest Sums

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

  7. [Swift]LeetCode373. 查找和最小的K对数字 | Find K Pairs with Smallest Sums

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

  8. 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 ...

  9. 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 ...

随机推荐

  1. 【bzoj】1927 [Sdoi2010]星际竞速

    [算法]最小费用最大流 [题解]跟滑雪略有类似,同样因为可以重复所以不是最小路径覆盖. 连向汇的边容量为1足矣,因为一个点只会出去一次(路径结束). bzoj 1927 [Sdoi2010]星际竞速 ...

  2. Spring理论基础-面向切面编程

    AOP是Aspect-Oriented Programming的缩写,中文翻译是面向切面编程.作为Spring的特征之一,是要好好学习的. 首先面向切面编程这个名称很容易让人想起面向对象编程(OOP) ...

  3. LCA入门题集小结

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目: How far away ? Time Limit: 2000/1000 MS (Jav ...

  4. poj 3104 Drying(二分查找)

    题目链接:http://poj.org/problem?id=3104 Drying Time Limit: 2000MS   Memory Limit: 65536K Total Submissio ...

  5. Java多线程学习(三)volatile关键字

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  6. 完全教程 Aircrack-ng破解WEP、WPA-PSK加密利器

    其 实关于无线基础知识的内容还是挺多的,但是由于本书侧重于BT4自身工具使用的讲解,若是再仔细讲述这些外围的知识,这就好比讲述DNS工具时还要把 DNS服务器的类型.工作原理及配置讲述一遍一样,哈哈, ...

  7. fork与vfork区别

    1. 地址空间各段拷贝: fork: 内核为子进程生成新的地址空间结构,拷贝父进程的代码段,数据空间,堆,栈到自身的地址空间,但注意:子进程的代码段并不会分配物理空间,而是指向父进程的代码段物理空间, ...

  8. python基础===如何优雅的写代码(转自网络)

    本文是Raymond Hettinger在2013年美国PyCon演讲的笔记(视频, 幻灯片). 示例代码和引用的语录都来自Raymond的演讲.这是我按我的理解整理出来的,希望你们理解起来跟我一样顺 ...

  9. ZZ:Solaris 10 软件包分析

    ZZ:Solaris 10 软件包分析 http://blog.chinaunix.net/uid-22759617-id-276756.html # Last updated: 2006-02-14 ...

  10. JS常用操作方法

    1.splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. 注释:该方法会改变原始数组. 1 <script type="text/javascript"& ...