两个有序数组间相加和的Topk问题;优先队列、最大堆。
取自:https://blog.csdn.net/weixin_44503157/article/details/117962906
一、思路
用最大堆来实现。然后再加上用个bfs来扫描周围的最大值。
即:
- 将右下角唯一知道的最大值压入最大堆;
- 弹出最大堆中最大的值,这个值就可以加入最终结果中;
- 将这个最大值的左边节点和上边节点加入最大堆中。
- 继续步骤2.的操作。直到压入了k个答案。
二、难点:
1、标记地址
堆中数据弹出,虽然知道是最大的,但是并不知道其所在坐标。
需要自己定一个数据结构。其中包含了val,和其坐标x、y;
然后定义最大堆的时候,用这个数据结构的val来作为构建堆时比较的值。
我使用了stl中的优先队列,定义的时候,可以声明其比较函数。
2、去重
单纯的这样bfs 可能会进到重复的坐标中。使得一个坐标的值进入两次。
我用集合 set来标记对应坐标,防止一个坐标重复进堆。
三、代码
struct nodde {
int val;
int x;
int y;
};
class mycomparison
{
public:
bool operator() (const nodde& lhs, const nodde&rhs) const
{
return (lhs.val < rhs.val);
}
};
vector<int> topK(vector<int> &arr1, vector<int>&arr2, int k)
{
int cur1 = arr1.size() - 1, cur2 = arr2.size() - 1;
priority_queue<nodde, std::vector<nodde>, mycomparison >
my_heap;
vector<int> result;
nodde temp, temp1, temp2;
temp.val = arr1[cur1] + arr2[cur2];
unordered_set<string> my_set;
temp.x = cur1;
temp.y = cur2;
my_heap.push(temp);
my_set.insert(to_string(cur1)+","+to_string(cur2));
int cnt = 0;
while (cnt < k)
{
temp = my_heap.top();
my_heap.pop();
temp1.x = temp.x - 1;
temp1.y = temp.y;
// if(temp.x>=0&&temp1.y>=0)
temp1.val = arr1[temp1.x] + arr2[temp1.y];
temp2.x = temp.x;
temp2.y = temp.y - 1;
temp2.val = arr1[temp2.x] + arr2[temp2.y];
result.push_back(temp.val);
if(my_set.count(to_string(temp1.x)+","+to_string(temp1.y)) ==0)
{
my_heap.push(temp1);
my_set.insert(to_string(temp1.x)+","+to_string(temp1.y));
}
if(my_set.count(to_string(temp2.x)+","+to_string(temp2.y)) ==0)
{
my_heap.push(temp2);
my_set.insert(to_string(temp2.x)+","+to_string(temp2.y));
}
cnt++;
}
return result;
}



京公网安备 11010502036488号