暴力循環+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;
}
};