373. Find K Pairs with Smallest Sums
- Total Accepted: 1453
- Total Submissions: 5789
- Difficulty: Medium
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:
Given nums1 = [1,7,11], nums2 = [2,4,6], k = 3 Return: [1,2],[1,4],[1,6] 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:
Given nums1 = [1,1,2], nums2 = [1,2,3], k = 2 Return: [1,1],[1,1] 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:
Given nums1 = [1,2], nums2 = [3], k = 3 Return: [1,3],[2,3] All possible pairs are returned from the sequence: [1,3],[2,3]
思路:
方法一:直接将pair(num1,num2)插入priority_queue中,将优先队列的元素按num1+num2升序排列,最后取前min(nums1.size()*nums2.size(),k)个返回。
方法二:方法一的优化。
方法三:对nums1中的每个元素num1保留对应的nums2元素num2位置的数组index。每次遍历nums1中的每个元素,对于nums1中的元素nums1[i],在nums2中搭配nums2[index[nums1[i]]],取最小的nums1[i]+nums2[index[nums1[i]]],然后将(nums1[i],nums2[index[nums1[i]]])插入到结果的向量中。
关于priority_queue的用法可以参考priority_queue的用法。
代码:
方法一:
1 class Solution { 2 public: 3 struct cmp{ 4 bool operator()(pair<int, int> num1,pair<int, int> num2){ 5 //priority_queue的比较函数用的是less函数: 6 //返回true时,num1的优先级低于num2(num1排在num2的后面) 7 return num1.first+num1.second>num2.first+num2.second; 8 } 9 }; 10 vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) { 11 vector<pair<int, int>> res; 12 priority_queue<pair<int, int>,vector<pair<int, int>>,cmp> pq; 13 int i,j,m=nums1.size(),n=nums2.size(); 14 for(i=0;i<m;i++){ 15 for(j=0;j<n;j++){ 16 pq.push(make_pair(nums1[i],nums2[j])); 17 } 18 } 19 while(k-->0&&pq.size()>0){ 20 res.push_back(pq.top()); 21 pq.pop(); 22 } 23 return res; 24 } 25 };
方法二:
1 class Solution { 2 public: 3 struct cmp{ 4 bool operator()(pair<int, int>& num1, pair<int, int>& num2){ 5 return num1.first + num1.second < num2.first + num2.second; 6 } 7 }; 8 vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) { 9 vector<pair<int, int>> res; 10 priority_queue<pair<int,int>, vector<pair<int, int> >, cmp> pq; 11 for(int i = 0; i < min((int)nums1.size(), k); i++){ 12 for(int j = 0; j < min((int)nums2.size(), k); j++){ 13 if(pq.size() < k) 14 pq.push(make_pair(nums1[i], nums2[j])); 15 else if(nums1[i] + nums2[j] < pq.top().first + pq.top().second){ 16 pq.push(make_pair(nums1[i], nums2[j])); 17 pq.pop(); 18 } 19 } 20 } 21 while(!pq.empty()){ 22 res.insert(res.begin(),pq.top()); 23 pq.pop(); 24 } 25 return res; 26 } 27 };
方法三:
1 class Solution { 2 public: 3 vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) { 4 vector<pair<int, int>> res; 5 int i,j,m=nums1.size(),n=nums2.size(); 6 vector<int> index(m,0); 7 k=min(k,m*n); 8 while(k-->0){ 9 int temp; 10 long long minv=LONG_MAX; 11 for(i=0;i<m;i++){ 12 if(index[i]<n&&minv>nums1[i]+nums2[index[i]]){ 13 minv=nums1[i]+nums2[index[i]]; 14 temp=i; 15 } 16 } 17 res.push_back(make_pair(nums1[temp],nums2[index[temp]])); 18 index[temp]++; 19 } 20 return res; 21 } 22 };