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:
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]
There are three ways to solve this problem, in approach #1(this is my own code) I use a vector to stroe the pair of nums1[i] and nums2[2] then sorting the vector. The time complex: O(N*M)
In approach #2, we use a struct of priority_queue to store the pair, this is the complete explaction.
In approach #3, we use bfs to search the minimum element from left-top to right-bottom. this is the complete explaction.
Approach #1: C++.[brute force]
class Solution {
public:
vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
vector<pair<int, int>> temp;
for (int i = 0; i < nums1.size(); ++i) {
for (int j = 0; j < nums2.size(); ++j) {
temp.push_back({nums1[i], nums2[j]});
}
}
sort(temp.begin(), temp.end(), cmp);
vector<pair<int, int>> ans;
for (int i = 0; i < temp.size() && i < k; ++i) {
ans.push_back(temp[i]);
}
return ans;
}
private:
static bool cmp(pair<int, int> a, pair<int, int> b) {
return a.first + a.second < b.first + b.second;
}
};
Approach #2: Java.
class Solution {
public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
PriorityQueue<int[]> que = new PriorityQueue<>((a, b)->a[0]+a[1]-b[0]-b[1]);
List<int[]> res = new ArrayList<>();
if (nums1.length == 0 || nums2.length == 0 || k == 0) return res;
for (int i = 0; i < nums1.length && i < k; i++)
que.offer(new int[]{nums1[i], nums2[0], 0});
while (k-- > 0 && !que.isEmpty()) {
int[] cur = que.poll();
res.add(new int[]{cur[0], cur[1]});
if (cur[2] == nums2.length-1) continue;
que.offer(new int[]{cur[0], nums2[cur[2]+1], cur[2]+1});
}
return res;
}
}
Approach #3: Python.
class Solution(object):
def kSmallestPairs(self, nums1, nums2, k):
"""
:type nums1: List[int]
:type nums2: List[int]
:type k: int
:rtype: List[List[int]]
"""
import heapq
ret = []
if len(nums1) * len(nums2) > 0:
queue = [(nums1[0] + nums2[0], (0, 0))]
visited = {}
while len(ret) < k and queue:
_, (i, j) = heapq.heappop(queue)
ret.append((nums1[i], nums2[j]))
if j + 1 < len(nums2) and (i, j+1) not in visited:
heapq.heappush(queue, (nums1[i] + nums2[j+1], (i, j+1)))
visited[(i, j+1)] = 1
if i + 1 < len(nums1) and (i+1, j) not in visited:
heapq.heappush(queue, (nums1[i+1] + nums1[j], (i+1, j)))
visited[(i+1, j)] = 1
return ret