k Smallest Sum Pairs From Two Arrays
Problem
Given two ascending arrays nums1 and nums2 and an integer k, return the k pairs (u, v) with the smallest values of u + v, where u comes from nums1 and v from nums2.
Input
nums1 = [1,7,11], nums2 = [2,4,6], k = 3Output
[[1,2],[1,4],[1,6]]Seed a min-heap with (nums1[0]+nums2[0], 0, 0). On each pop (i, j), push (i, j+1); also push (i+1, 0) the first time j is 0. The heap holds at most k frontier pairs.
import heapq
def k_smallest_pairs(nums1, nums2, k):
if not nums1 or not nums2: return []
heap = [(nums1[0] + nums2[0], 0, 0)]
seen = {(0, 0)}
out = []
while heap and len(out) < k:
s, i, j = heapq.heappop(heap)
out.append([nums1[i], nums2[j]])
for di, dj in ((0, 1), (1, 0)):
ni, nj = i + di, j + dj
if ni < len(nums1) and nj < len(nums2) and (ni, nj) not in seen:
seen.add((ni, nj))
heapq.heappush(heap, (nums1[ni] + nums2[nj], ni, nj))
return out
// Uses a binary min-heap on [sum, i, j] (heap class omitted).
function kSmallestPairs(nums1, nums2, k) {
if (!nums1.length || !nums2.length) return [];
const heap = new MinHeap((a, b) => a[0] - b[0]);
const seen = new Set(["0,0"]);
heap.push([nums1[0] + nums2[0], 0, 0]);
const out = [];
while (heap.size() && out.length < k) {
const [, i, j] = heap.pop();
out.push([nums1[i], nums2[j]]);
for (const [di, dj] of [[0, 1], [1, 0]]) {
const ni = i + di, nj = j + dj, key = ni + "," + nj;
if (ni < nums1.length && nj < nums2.length && !seen.has(key)) {
seen.add(key);
heap.push([nums1[ni] + nums2[nj], ni, nj]);
}
}
}
return out;
}
class Solution {
public List<List<Integer>> kSmallestPairs(int[] a, int[] b, int k) {
List<List<Integer>> out = new ArrayList<>();
if (a.length == 0 || b.length == 0) return out;
PriorityQueue<int[]> pq = new PriorityQueue<>((x, y) -> x[0] - y[0]);
Set<Long> seen = new HashSet<>();
pq.add(new int[]{a[0] + b[0], 0, 0});
seen.add(0L);
while (!pq.isEmpty() && out.size() < k) {
int[] t = pq.poll();
int i = t[1], j = t[2];
out.add(Arrays.asList(a[i], b[j]));
int[][] nb = {{i, j + 1}, {i + 1, j}};
for (int[] p : nb) {
if (p[0] < a.length && p[1] < b.length) {
long key = (long) p[0] * 100000 + p[1];
if (seen.add(key)) pq.add(new int[]{a[p[0]] + b[p[1]], p[0], p[1]});
}
}
}
return out;
}
}
vector<vector<int>> kSmallestPairs(vector<int>& a, vector<int>& b, int k) {
vector<vector<int>> out;
if (a.empty() || b.empty()) return out;
priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;
set<pair<int,int>> seen;
pq.emplace(a[0] + b[0], 0, 0);
seen.insert({0, 0});
while (!pq.empty() && (int) out.size() < k) {
auto [s, i, j] = pq.top(); pq.pop();
out.push_back({a[i], b[j]});
for (auto [di, dj] : {make_pair(0,1), make_pair(1,0)}) {
int ni = i + di, nj = j + dj;
if (ni < (int) a.size() && nj < (int) b.size() && seen.insert({ni, nj}).second)
pq.emplace(a[ni] + b[nj], ni, nj);
}
}
return out;
}