一.题目:
从两个数组中各拿出一个数字,求两个数字的和最小的k个组合。如果和相等的时候,出现的顺序是不在乎的。
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]
二.解题思路:
(1)方法一
从例1中我们可以得到暴力的解法,首先递归得到所有的组合,然后取出其中和最小的前k个组合.代码如下:
class Solution(object):
def kSmallestPairs(self, nums1, nums2, k):
"""
:type nums1: List[int]
:type nums2: List[int]
:type k: int
:rtype: List[List[int]]
"""
dicts = collections.defaultdict(list)
lists = [nums1,nums2]
def dfs(index,lists,res,dicts):
if index == 2:
dicts[sum(res)] +=[res]
return
for i in lists[index]:
dfs(index+1,lists,res+[i],dicts)
dfs(0,lists,[],dicts)
result = []
for key in sorted(dicts.keys()):
for i in dicts[key]:
if len(result) < k:
result.append(i)
elif len(result) == k:
return result
return result
(2)方法二
从各个组合中找到前k个和最小的组合,从这里看我们可以尝试使用堆来实现.首先将(nums1[i] + nums2[0], i, 0)加入堆,i取值范围[0, size1);然后弹出堆顶元素sum, i, j,将(nums1[i], nums2[j])加入结果集ans,若j + 1 < size2,则将(nums1[i] + nums2[j + 1], i, j + 1)加入堆.代码如下:
class Solution(object):
def kSmallestPairs(self, nums1, nums2, k):
"""
:type nums1: List[int]
:type nums2: List[int]
:type k: int
:rtype: List[List[int]]
"""
res = []
len1, len2 = len(nums1), len(nums2)
if not len1 or not len2: return res
heap = []
for x in range(len1):
heapq.heappush(heap, (nums1[x] + nums2[0], x, 0))
while len(res) < min(k, len1 * len2):
sum, i, j = heapq.heappop(heap)
res.append([nums1[i], nums2[j]])
if j + 1 < len2:
heapq.heappush(heap, (nums1[i] + nums2[j + 1], i, j + 1))
return res