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.
题目链接:
https://leetcode.com/problems/find-k-pairs-with-smallest-sums/
这题犯2了,想了个思路,实现了好久,很麻烦,但因为思路是错的,最后还是错的。
一开始就想找最好的方法,但想出来的方法又是错的,所以啥也没干成。
其实一个题目到手的时候,先想最brute force的方法,这样至少有一个保底的方法,然后再想想是不是可以优化一下,是不是有更好的算法,这样的顺序可能更好一点。
这题这里有一个比较好的循序渐进的解法:
http://www.cnblogs.com/grandyang/p/5653127.html
思路比较难理解,理一理,递归解决,假设我们已经得到了第m个pair pij,那么下一个pair肯定是p(i+1, j)或者是p(i, j+1)中间的一个,但是不能把这两个都推进去,因为可能会有重复,比如如果之前已经有最小的 p(i+1, j-1)或者有最小的p(i-1, j+1)的话,那priority_tree里头肯定就存在p(i+1,j)或者p(i, j+1)的一个了,这样就重复了。
简单的解决办法: 增加1个机制判断是否已经访问过,访问过的话就不加了。我用了一个unordered_set<int> 来做判断,
开始用的不是int而是pair<int, int>,但是这个需要自己写hash函数,所以还是改成int,用i * nums2.size() + j做key value
<span style="color:#000000;">class Solution {
public:
vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
vector<pair<int, int> > result;
unordered_set<int> visited;//judge weh
auto comp = [&nums1, &nums2](const pair<int,int>& p1, const pair<int, int>& p2){
return nums1[p1.first] + nums2[p1.second] > nums1[p2.first] + nums2[p2.second];
};
priority_queue<pair<int, int>, vector<pair<int,int> >, decltype(comp) > pair_q(comp);
if(nums1.size() == 0 || nums2.size() == 0) return result;
pair_q.push(pair<int,int>(0, 0));
visited.insert(0);
while(pair_q.size() && result.size() < k){
pair<int, int> cur_pair = pair_q.top();
result.emplace_back(nums1[cur_pair.first], nums2[cur_pair.second]);
pair_q.pop();
if(cur_pair.first+1 < nums1.size()){
pair<int,int> next_pair(cur_pair.first+1, cur_pair.second);
int key = next_pair.first * nums2.size() + next_pair.second;
if(visited.find(key) == visited.end()) {
visited.insert(key);
pair_q.push(next_pair);
}
}
if(cur_pair.second+1 < nums2.size()){
pair<int,int> next_pair(cur_pair.first, cur_pair.second+1);
int key = next_pair.first * nums2.size() + next_pair.second;
if(visited.find(key) == visited.end()) {
visited.insert(key);
pair_q.push(next_pair);
}
}
}
return result;
}
};</span>
class Solution {
public:
vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
vector<pair<int, int> > result;
auto comp = [&nums1, &nums2](const pair<int,int>& p1, const pair<int, int>& p2){
return nums1[p1.first] + nums2[p1.second] > nums1[p2.first] + nums2[p2.second];
};
priority_queue<pair<int, int>, vector<pair<int,int> >, decltype(comp) > pair_q(comp);
if(nums1.size() == 0 || nums2.size() == 0) return result;
pair_q.push(pair<int,int>(0, 0));
while(pair_q.size() && result.size() < k){
pair<int, int> cur_pair = pair_q.top();
result.emplace_back(nums1[cur_pair.first], nums2[cur_pair.second]);
pair_q.pop();
if(cur_pair.first+1 < nums1.size() && cur_pair.second == 0)
pair_q.emplace(cur_pair.first+1, cur_pair.second);
if(cur_pair.second+1 < nums2.size())
pair_q.emplace(cur_pair.first, cur_pair.second+1);
}
return result;
}
};