暴力循环+BFS
因为要求每个0到1的最近距离,所以对于每个0进行BFS,搜到1时停止。然后挑出最大值即可。
这是最朴素的做法了。
循环 n^2次,每次(n ^2)
时间复杂度:
const int dx[] = {-1,0,1,0};
const int dy[] = {0,1,0,-1};
class Solution {
public:
int m,n;
typedef pair<int,int> P;
int maxDistance(vector<vector<int>>& grid) {
m = grid.size();
n = grid[0].size();
int tot = 0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
tot += grid[i][j];
}
}
if(tot==0 || tot ==m*n){
return -1;
}
int mmax = 0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]){ continue; }
int x = bfs(i,j,grid);
// cout<<x<<" "<<i<<":"<<j<<endl;
mmax = max(x,mmax);
}
}
return mmax;
}
int bfs(int i,int j,vector<vector<int>>& grid){
queue<P> q;
q.push(P(i,j));
int dpt = 1;
int vis[110][110] = {0};
while(!q.empty()){
int size = q.size();
while(size--){
P p = q.front();
q.pop();
int x = p.first ,y = p.second;
for(int k=0;k<4;k++){
int nx = x+dx[k];
int ny = y+dy[k];
if(nx>=0 && nx<m && ny>=0 && ny<n && !vis[nx][ny] && grid[nx][ny]==0){
q.push(P(nx,ny));
vis[nx][ny] = 1;
}
if(nx>=0 && nx<m && ny>=0 && ny<n && grid[nx][ny]==1){
return dpt;
}
}
}
dpt++;
}
return 0;
}
};
多个等价起始状态的BFS
改变一下思路,将所有的1全部作为起点加入队列,然后去遍历整张图,最后一个被搜索到的0就是离所有1曼哈顿距离最大的。
(图片来自互联网 )
时间复杂度:
const int dx[] = {-1,0,1,0};
const int dy[] = {0,1,0,-1};
class Solution {
public:
int maxDistance(vector<vector<int>>& grid) {
typedef pair<int,int> P;
queue<P> q;
int m = grid.size(),n = grid[0].size();
int d[110][110];
memset(d,-1,sizeof(d));
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]){
q.push(P(i,j));
d[i][j] = 0;
}
}
}
if(q.size()==0 || q.size()==m*n){
return -1;
}
int ans = 0;
while(!q.empty()){
int size = q.size();
while(size--){
P p = q.front();
q.pop();
int x = p.first;
int y = p.second;
for(int k=0;k<4;k++){
int nx = x+dx[k];
int ny = y+dy[k];
if(nx>=0 && nx<m && ny>=0 && ny<n
&& d[nx][ny]==-1 ){
d[nx][ny] = d[x][y]+1;
q.push(P(nx,ny));
ans = max(ans,d[nx][ny]);
}
}
}
}
return ans;
}
};
DP
DP题日后再刷
class Solution {
public:
int maxDistance(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
//赋初值
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==0){
grid[i][j] = 1e9;
}else{
grid[i][j] = 0;
}
}
}
//从左上到右下
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(i-1>=0){
grid[i][j] = min(grid[i-1][j]+1,grid[i][j]);
}
if(j-1>=0){
grid[i][j] = min(grid[i][j-1]+1,grid[i][j]);
}
}
}
//从右下到左上
for(int i=m-1;i>=0;i--){
for(int j=n-1;j>=0;j--){
if(i+1<m){
grid[i][j] = min(grid[i+1][j]+1,grid[i][j]);
}
if(j+1<n){
grid[i][j] = min(grid[i][j+1]+1,grid[i][j]);
}
}
}
//遍历
int ans = -1;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
ans = max(ans,grid[i][j]);
}
}
if(ans==0 || ans==1e9){
return -1;
}
return ans;
}
};