题目太长了放链接
力扣5973
思路
题目很长,思路直接但东西很多,topK问题(小顶堆)+BFS
通过BFS从起点开始探索,将满足条件的节点存入topK的优先队列中,答案就是优先队列中的节点;
因为要记录步长,还需要类似层序遍历那样逐步遍历;
因为四个方向都要探索,所以用哈希set存储已访问过的节点,并用点字符串哈希的思想用一个int表示坐标 即x*13131 + y
另外注意的点在优先级中步数是优先级最高的,而探索的过程中步长是一直增加的,所以当该层遍历完,如果优先队列中的元素个数够了就可以直接退出,因为后续的优先级肯定更低;
代码
class Solution {
public:
struct node {
int val, dis, x, y;
bool operator < (const node & a) const {
if(dis == a.dis) {
if(val == a.val) {
if(x == a.x) {
return y > a.y;
}
else return x > a.x;
}
else return val > a.val;
}
else return dis > a.dis;
}
};
priority_queue<node> qnode;
queue<pair<int, int> > q;
unordered_set<int> vis;
int seed = 13131;
int m, n;
vector<vector<int>> highestRankedKItems(vector<vector<int>>& grid, vector<int>& pricing, vector<int>& start, int k) {
m = grid.size();
n = grid[0].size();
vector<vector<int> > dir = {{0,1}, {0,-1}, {1,0}, {-1,0}};
vector<vector<int>> ans;
if(grid[start[0]][start[1]] == 0) return ans;
q.push({start[0], start[1]});
vis.insert(start[0]*seed + start[1]);
int dis = -1;
while(!q.empty()) {
int cnt = q.size();
dis++;
while(cnt--) {
auto [x,y] = q.front();
q.pop();
int val = grid[x][y];
if(val == 0) continue;
else {
if(val >= pricing[0] && val <= pricing[1]) {
node tmp;
tmp.val = val; tmp.dis = dis;
tmp.x = x; tmp.y = y;
qnode.push(tmp);
}
for(auto d : dir) {
int nx = x + d[0], ny = y + d[1];
if(nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
if(vis.count(nx*seed + ny)) continue;
if(grid[nx][ny] != 0) {
vis.insert(nx*seed + ny);
q.push({nx, ny});
}
}
}
}
if(qnode.size() >= k) break;
}
while(!qnode.empty() && k--) {
node tmp = qnode.top();
qnode.pop();
ans.push_back({tmp.x, tmp.y});
}
return ans;
}
};