542.01 矩阵
这道题和最大岛屿问题还是有一定区别的,使用深搜比较麻烦。其实可以将这道题转换成动态规划问题或者广搜问题会比较好解决一点。
DP方法:先正序遍历矩阵,每次根据左方和上方已经得出的结果来更新矩阵。再逆序遍历矩阵,根据右方和下方值来更新矩阵。两次遍历得到最终矩阵。
public int[][] updateMatrix(int[][] mat) {
int row = mat.length;
int col = mat[0].length;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (mat[i][j] == 1) {
mat[i][j] = Integer.MAX_VALUE;
}
if (i > 0) {
mat[i][j] = Math.min(mat[i][j], mat[i - 1][j] + 1);
}
if (j > 0) {
mat[i][j] = Math.min(mat[i][j], mat[i][j - 1] + 1);
}
}
}
for (int i = row - 1; i > 0; i--) {
for (int j = col - 1; j > 0; j--) {
if (i < row - 1) {
mat[i][j] = Math.min(mat[i][j], mat[i + 1][j] + 1);
}
if (j < col - 1) {
mat[i][j] = Math.min(mat[i][j], mat[i][j + 1] + 1);
}
}
}
return mat;
}
BFS方法:该方法先将矩阵里所有0元素加入队列,然后0元素出队,附近不为0的元素入队,以此类推。
public int[][] updateMatrix(int[][] mat) {
int[][] vector = {{0,1},{1,0},{0,-1},{-1,0}};
int row = mat.length;
int col = mat[0].length;
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < row; i++){
for (int j = 0; j < col; j++){
if(mat[i][j] == 0){
queue.add(new int[]{i,j});
}else {
mat[i][j] = Integer.MAX_VALUE;
}
}
}
while(!queue.isEmpty()){
int[] n = queue.poll();
for(int[] v : vector){
int nr = n[0] + v[0], nc = n[1] + v[1];
if(nr >= 0 && nc >= 0 && nr < row && nc < col && mat[nr][nc] > mat[n[0]][n[1]] + 1){
mat[nr][nc] = mat[n[0]][n[1]] + 1;
queue.add(new int[]{nr,nc});
}
}
}
return mat;
}
DFS不太适合这道题,虽然可以做,为了不影响思路,就不记录DFS的方法了。
994.腐烂的橘子
这道题可以借鉴上一道一的BFS方法,只不过要注意[[0]],[[1]],[[0,1]],这些特殊情况。正常情况下,一次要将队列中所有的腐烂苹果出队。当最后一个腐烂的苹果加入队列时,其实所有的苹果都已经腐烂了,但这个时候队列不为空,还要再进行一次循环,所以最后minute要减一。最后,再次遍历整个数组,如果还存在1值,说明有苹果没办法腐烂,因此返回-1。
public int orangesRotting(int[][] grid) {
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 2) {
queue.add(new int[]{i, j});
}
}
}
if (queue.isEmpty()) {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
return -1;
}
}
}
return 0;
}
int minute = 0;
int[][] vector = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
while (!queue.isEmpty()) {
List<int[]> list = new LinkedList<>();
int size = queue.size();
for (int i = 0; i < size; i++) {
list.add(queue.poll());
}
for (int[] n : list) {
for (int[] v : vector) {
int nr = n[0] + v[0];
int nc = n[1] + v[1];
if (nr >= 0 && nc >= 0 && nr < grid.length && nc < grid[0].length && grid[nr][nc] == 1) {
grid[nr][nc] = 2;
queue.add(new int[]{nr, nc});
}
}
}
minute++;
}
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
return -1;
}
}
}
minute -= 1;
return minute;
}