---
# System prepended metadata

title: 373. Find K Pairs with Smallest Sums
tags: [heap, Leetcode, medium, python, c++]

---

###### 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;
    }
};
```