本来想着用海去找陆地…发现只能每片海都需要做一次BFS,那么算下来就是n2次BFS,最差的情况 O(n3)的时间复杂度,不出意外的果然超了(不超俺也不会写优化版本了2333)
class Solution {
public int maxDistance(int[][] grid) {
int max = -1;
for(int i=0;i<grid.length;i++){
for(int j =0;j<grid[0].length;j++){
if(grid[i][j]==1){
continue;
}
Queue<Point> queue = new LinkedList<>();
Set<Point> set = new HashSet<>();
int this_max = Integer.MAX_VALUE;
queue.add(new Point(j,i));
while(!queue.isEmpty()){
Point p = queue.poll();
if(p.x<0||p.x>=grid[0].length||p.y<0||p.y>=grid.length){
continue;
}
if(set.contains(p)){
continue;
}
set.add(p);
if(grid[p.y][p.x]==1){
this_max = Math.min(this_max,Math.abs(p.x-j)+Math.abs(p.y-i));
break;
}
queue.add(new Point(p.x-1,p.y));
queue.add(new Point(p.x+1,p.y));
queue.add(new Point(p.x,p.y-1));
queue.add(new Point(p.x,p.y+1));
}
max = Math.max(this_max,max);
}
}
return max==Integer.MAX_VALUE?-1:max;
}
}
class Point{
int x,y;
Point(int xx,int yy){
x = xx;
y = yy;
}
@Override
public int hashCode() {
return Objects.hash(this.x,this.y);
}
@Override
public boolean equals(Object obj) {
if(obj==this){
return true;
}
if(obj instanceof Point){
Point p = (Point) obj;
return x==p.x&&y==p.y;
}
return obj==this;
}
}
出现这么大的时间复制度就是因为有很多重复的BFS,用一块较为靠中的海去找最近陆地肯定也会经过前面已经找过的海,不过,由于有四个方向(有两个方向是还未探索过),由不能完全用前面的替代,更新起来也会比较麻烦,所以用类动规的思路其实也不太好写。
那么我们换个思路,如果说找离大海最远的陆地,那么我们找离陆地最远的大海好了,从多个陆地出发,广度优先的搜索,遇到更新过的海域便不做处理,最后个更新的值自然就是最远的距离了。
class Solution {
public int maxDistance(int[][] grid) {
int max = 0;
Queue<int[]> queue = new LinkedList<>();
int[] dx = new int[]{0,1,0,-1};
int[] dy = new int[]{1,0,-1,0};
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[0].length;j++){
if(grid[i][j]==1){
queue.offer(new int[]{i,j});
}
}
}
if(queue.size()==0||queue.size()==grid[0].length*grid.length){
return -1;
}
int y_size = grid.length,x_size = grid[0].length;
int[] point = null;
while (!queue.isEmpty()){
point = queue.poll();
for(int i=0;i<4;i++){
int n_x = point[1]+dx[i],
n_y = point[0]+dy[i];
if(n_x<0||n_y<0||n_x==x_size||n_y==y_size||grid[n_y][n_x]!=0){
continue;
}
queue.offer(new int[]{n_y,n_x});
grid[n_y][n_x] = grid[point[0]][point[1]]+1;
}
}
return grid[point[0]][point[1]]-1;
}
}