原题地址:点我传送
有想法是用广度优先做,但是感觉可能会太耗时间,就想按顺序遍历,给每个1取临近的1的距离值+1中最小的,如果临近有0则距离必为1最小(实际上这样访问的只能是左边和上面的1,因为后面的1的距离值还没有算出来)。但是这样会有一个问题,即后面出现临近的0时右边或者下面的与新出现的0临近的点的距离值还没有算出来,无法给当前算的距离值提供,而此时新出现的0可能会带来更小的距离值。于是就再加上一个倒序遍历,每次检测临近的右下的1或0。两次遍历后的距离值取最小者即是所求。代码虽然长,但是思路是简单的,耗时似乎也不长。
Java:
public class Solution { public int[][] updateMatrix(int[][] matrix) { int n = matrix.length; int m = matrix[0].length; int dis[][] = new int [n][m]; boolean finded[][] = new boolean [n][m]; for(int i = 0;i < n;i++) // pre-order { for(int j = 0;j < m;j++) { if(matrix[i][j]==0) { dis[i][j]=0; } else if(matrix[i][j]==1) { int ans=n+m+10; //value that impossible to reach if(i-1>=0)//left { if(matrix[i-1][j]==0) { dis[i][j]=1; continue; } else { ans=Math.min(ans,dis[i-1][j]+1); } } if(j-1>=0)//up { if(matrix[i][j-1]==0) { dis[i][j]=1; continue; } else { ans=Math.min(ans,dis[i][j-1]+1); } } dis[i][j] = ans; } } } for(int i = n-1;i >= 0;i--) // post-order { for(int j = m-1;j >= 0;j--) { if(matrix[i][j]==0) { dis[i][j]=0; } else if(matrix[i][j]==1) { int ans=n+m+10; //value that impossible to reach if(i+1<n)//right { if(matrix[i+1][j]==0) { dis[i][j]=1; continue; } else { ans=Math.min(ans,dis[i+1][j]+1); } } if(j+1<m)//down { if(matrix[i][j+1]==0) { dis[i][j]=1; continue; } else { ans=Math.min(ans,dis[i][j+1]+1); } } dis[i][j] = Math.min(ans,dis[i][j]); } } } return dis; } }