BFS
对于每个询问,因为需要严格小于询问的元素,因此宽搜的队列改用优先队列。
每次BFS都从队列中取出最小的元素,如果它大于p,则更新p;否则不更新,然后用数组f来记录BFS到的不超过p的元素有多少个。
BFS结束后,得到f数组,然后求f的前缀和数组,这样就可以O(1)回答所有询问。
class Solution {
public:
int f[1000010];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
vector<int> maxPoints(vector<vector<int>>& g, vector<int>& qy) {
memset(f,0,sizeof f);
int n=g.size(),m=g[0].size();
vector<vector<int>> vis(n,vector<int>(m,0));
int p=g[0][0];
vis[0][0]=1;
priority_queue<tuple<int,int,int>,vector<tuple<int,int,int>>,greater<tuple<int,int,int>>> q;
q.push({g[0][0],0,0});
while(!q.empty()){
auto [d,x,y]=q.top();
q.pop();
if(d>p) p=d;
f[p]++;
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(xx<0||xx>=n||yy<0||yy>=m||vis[xx][yy]) continue;
vis[xx][yy]=1;
q.push({max(g[xx][yy],d),xx,yy});
}
}
for(int i=1;i<=1000008;i++){
f[i]+=f[i-1];
}
int l=qy.size();
vector<int> ans(l);
for(int i=0;i<l;i++) ans[i]=f[qy[i]-1];
return ans;
}
};
时间复杂度:O(nmlognm),n、m分别为矩阵的长、宽。
空间复杂度:O(nm)。
另外,此题也可以并查集离线处理来解决。