题目描述:
给定两个以 升序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 。
定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 。
请找到和最小的 k 个数对 (u1,v1), (u2,v2) ... (uk,vk) 。
样例:
方法一:
class Solution {
public:
struct Node
{
int i, j; //分别表示nums1中的下标和nums2中的下标
int x, y; //分别代表nums1[i]的值和nums2[j]的值
//因为优先队列默认使用<,所以要重载<
//这里的两个const都必须添加
bool operator< (const Node& a) const
//这里的<比较的是优先级,而不是比较大小,返回true时,说明this的优先级低于a
//x + y值较大的Node优先级低(x + y小的Node排在队前)
{
return x + y > a.x + a.y;
}
};
vector<vector<int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) {
priority_queue<Node> prique;
for (int i = 0; i < nums1.size(); i++)
{
Node cur;
cur.i = i;
cur.j = 0;
cur.x = nums1[i];
cur.y = nums2[0];
prique.push(cur);
}
vector<vector<int>> ans;
int i = 0;
while (i++ < k && !prique.empty())
{
Node cur = prique.top();
prique.pop();
ans.push_back({cur.x, cur.y});
Node newnode;
if (cur.j + 1 < nums2.size())
{
newnode.i = cur.i;
newnode.j = cur.j + 1;
newnode.x = nums1[newnode.i];
newnode.y = nums2[newnode.j];
prique.push(newnode);
}
}
return ans;
}
};
昨天病倒了,今天来补一下昨天的题目。
这道题真是受益匪浅,多路归并这个知识点对我来说是个盲区,之后值得好好看看。
这道题让我最费工夫的倒是优先队列的自定义排序这个部分,网上找了很多博客,每篇都有些不一样的地方,在写题时又纠结于两个const:
bool operator< (const Node& a) const
{
return x + y > a.x + a.y;
}
这里的两个const不能省略,第一个const修饰的是a,第二个const修饰的是this,因为在原优先队列的比较函数中就是使用两个常数来比较:
// STRUCT TEMPLATE less
template <class _Ty = void>
struct less {
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty _FIRST_ARGUMENT_TYPE_NAME;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty _SECOND_ARGUMENT_TYPE_NAME;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool _RESULT_TYPE_NAME;
_NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const {
return _Left < _Right;
}
};
所以去掉两个const的话,就相当于要将两个常数传入可以修改他们值的函数中,这是不允许的。