###### tags: `Leetcode` `medium` `heap` `python` `c++`
# 373. Find K Pairs with Smallest Sums
## [題目連結:] https://leetcode.com/problems/find-k-pairs-with-smallest-sums/
## 題目:
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.
Return the ```k``` pairs ```(u1, v1), (u2, v2), ..., (uk, vk)``` with the smallest sums.
**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]
```
## 解題想法:
* 此題為,給num1、num2皆為由小到大排序
* return 前k個最小和的pair(u,v)
* u: from nums1
* v: from nums2
* 使用heap queue進行儲存:
* Step1:
* **將nums1中每個元素與nums2[0]匹配存於queue**
* 儲存的pair **(總和, pos in nums1, pos in nums2)**
* Step2:
* 因為ex3,題目表明k有可能大於len(nums1) * len(nums2)的總長
* while len(res)< min(k, len(nums1) * len(nums2)):
* Step3: while中進行判斷
* 每次heappop最小的存於res
* sum,i,j=heapq.heappop(heap)
* i=pos in nums1
* j=pos in nums2
* 最後需要判斷: if j+1<len(nums2):
* heappush(heap,(nums1[i]+nums2[j+1],i,j+1))
* 因為: i很小立了大功 看看其他j有沒有機會分杯羹
## Python:
``` 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]]
"""
que=[]
#將nums1中每個元素與nums2[0]匹配存於que
#(總和,pos in nums1, pos in nums2)
for pos,val in enumerate(nums1):
heappush(que,(val+nums2[0], pos, 0)) #由總和小至大
res=[]
#填滿res
while len(res)< min(k, len(nums1)*len(nums2)):
curSum, i, j=heappop(que)
res.append([nums1[i], nums2[j]])
if j+1<len(nums2): #i很小立了大功 看看其他j有沒有機會分杯羹
heappush(que,(nums1[i]+nums2[j+1], i, j+1))
return res
```
## c++:
``` cpp=
class Solution {
public:
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
int len1=nums1.size(), len2=nums2.size();
//max_heap
priority_queue<vector<int>> que;
for (int pos1=0; pos1<len1; pos1++){
que.push({-(nums1[pos1]+nums2[0]), pos1, 0});
}
vector<vector<int>> res;
while (res.size()< k){
//while 判斷改成 res.size()< min(k, len1*len2) 會發生signed integer overflow: 99994 * 99998 cannot be represented in type 'int' (solution.cpp) :"(
if (que.empty()) //所以直接用判斷que是否為空跳出while進行判斷 就可以通過了
break;
vector<int> curItem=que.top(); que.pop();
int i=curItem[1], j=curItem[2];
res.push_back({nums1[i], nums2[j]});
if (j+1<len2)
que.push( {-(nums1[i]+nums2[j+1]), i, j+1});
}
return res;
}
};
```