Timeline
Timeline
2025-12-08
init
heap
Problem:
This problem cannot use two pointers because it is not linear. The core of solving it with a heap is to first put all {nums1[0], nums2[j]} into the heap (0 <= j <= nums2.size()), then pop the pair {i,j} with the smallest sum from the heap. With j unchanged, among the values greater than it, {i+1, j} is the smallest.
Then why can we keep j unchanged? Because the advancement of j (i.e., j+1) has already been fully added to the heap during initialization ({num1[0], nums2[j]}).
of Example 1nums1 = [1, 7, 11],nums2 = [2, 4, 6]We compute the sum of each pair, and we can get a matrix , where .
Sincenums2are increasing, so each row of the matrix is increasing. The problem is equivalent to: merge sorted lists and find the first smallest elements. (where isnums1the length of) According to the heap approach of P23 Merge K Sorted Lists:
- Add the first number of each row of the matrix and its position to the min-heap.
- Loop times.
- Each iteration, pop the heap top, and the heap top 's corresponding pair is added to the answer, and the element to the right of the heap top and its position into the heap.
1234567891011121314151617181920212223242526272829303132333435363738394041424344 | using std::vector;using std::pair;using std::priority_queue;using std::array;class Solution { public: vector<vector<int> > kSmallestPairs(vector<int> &nums1, vector<int> &nums2, int k) { vector<vector<int> > res; if (nums1.empty() || nums2.empty() || k == 0) return res; auto cmp = [&](const array<int, 2> &a, const array<int, 2> &b) { return nums1[a[0]] + nums2[a[1]] > nums1[b[0]] + nums2[b[1]]; }; priority_queue<array<int, 2>, vector<array<int, 2> >, decltype(cmp)> pq(cmp); for (int i = 0; i < nums1.size() && i < k; i++) { pq.push({ i, 0 }); } while (k-- && !pq.empty()) { auto [i, j] = pq.top(); pq.pop(); res.push_back({ nums1[i], nums2[j] }); if (j + 1 < nums2.size()) { pq.push({ i, j+1 }); } } return res; }}; |
