力扣5973——价格范围内最高排名的 K 样物品(优先队列+BFS层序遍历)

题目太长了放链接
力扣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;      
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值