2021.09.24 - 079.01 矩阵

文章目录

1. 题目

2021.09.24 - 079.01 矩阵

2. 思路

(1) BFS(超时)

  • 遍历二维数组,当遇到1时,对其进行广度优先搜索,找到距离其最近的一个0,并返回路径长度。
  • 在极端情况下容易超时。

(2) BFS优化

  • 将二维数组中所有的0看作一个整体,同时加入队列,然后以这个整体为原点进行广度优先搜索,一层一层地向外扩展,路径长度逐层加1。

(3) 动态规划

  • 完全没看懂。

3. 代码

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

public class Test {
    public static void main(String[] args) {
    }
}

class Solution {
    public int[][] updateMatrix(int[][] mat) {
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat[0].length; j++) {
                if (mat[i][j] == 1) {
                    mat[i][j] = bfs(mat, i, j);
                }
            }
        }
        return mat;
    }

    private int bfs(int[][] mat, int i, int j) {
        int dist = 0;
        Queue<int[]> queue = new LinkedList<>();
        boolean[][] flag = new boolean[mat.length][mat[0].length];
        queue.offer(new int[]{i, j});
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int k = 0; k < size; k++) {
                int[] index = queue.poll();
                flag[index[0]][index[1]] = true;
                if (index[0] > 0) {
                    if (mat[index[0] - 1][index[1]] == 0) {
                        return ++dist;
                    } else if (!flag[index[0] - 1][index[1]]) {
                        queue.offer(new int[]{index[0] - 1, index[1]});
                    }
                }
                if (index[0] < mat.length - 1) {
                    if (mat[index[0] + 1][index[1]] == 0) {
                        return ++dist;
                    } else if (!flag[index[0] + 1][index[1]]) {
                        queue.offer(new int[]{index[0] + 1, index[1]});
                    }
                }
                if (index[1] > 0) {
                    if (mat[index[0]][index[1] - 1] == 0) {
                        return ++dist;
                    } else if (!flag[index[0]][index[1] - 1]) {
                        queue.offer(new int[]{index[0], index[1] - 1});
                    }
                }
                if (index[1] < mat[0].length - 1) {
                    if (mat[index[0]][index[1] + 1] == 0) {
                        return ++dist;
                    } else if (!flag[index[0]][index[1] + 1]) {
                        queue.offer(new int[]{index[0], index[1] + 1});
                    }
                }
            }
            dist++;
        }
        return dist;
    }
}

class Solution1 {
    public int[][] updateMatrix(int[][] mat) {
        int row = mat.length;
        int col = mat[0].length;
        int[][] res = new int[row][col];
        boolean[][] flag = new boolean[row][col];
        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.offer(new int[]{i, j});
                    flag[i][j] = true;
                }
            }
        }
        while (!queue.isEmpty()) {
            int[] index = queue.poll();
            int x = index[0];
            int y = index[1];
            if (x > 0 && !flag[x - 1][y]) {
                res[x - 1][y] = res[x][y] + 1;
                queue.offer(new int[]{x - 1, y});
                flag[x - 1][y] = true;
            }
            if (x < row - 1 && !flag[x + 1][y]) {
                res[x + 1][y] = res[x][y] + 1;
                queue.offer(new int[]{x + 1, y});
                flag[x + 1][y] = true;
            }
            if (y > 0 && !flag[x][y - 1]) {
                res[x][y - 1] = res[x][y] + 1;
                queue.offer(new int[]{x, y - 1});
                flag[x][y - 1] = true;
            }
            if (y < col - 1 && !flag[x][y + 1]) {
                res[x][y + 1] = res[x][y] + 1;
                queue.offer(new int[]{x, y + 1});
                flag[x][y + 1] = true;
            }
        }
        return res;
    }
}

class Solution2 {
    public int[][] updateMatrix(int[][] mat) {
        int row = mat.length;
        int col = mat[0].length;
        int[][] res = new int[row][col];
        for (int i = 0; i < row; i++) {
            Arrays.fill(res[i], Integer.MAX_VALUE / 2);
        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (mat[i][j] == 0) {
                    res[i][j] = 0;
                }
            }
        }
        // 只有 水平向左移动 和 竖直向上移动,注意动态规划的计算顺序
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (i > 0) {
                    res[i][j] = Math.min(res[i][j], res[i - 1][j] + 1);
                }
                if (j > 0) {
                    res[i][j] = Math.min(res[i][j], res[i][j - 1] + 1);
                }
            }
        }
        // 只有 水平向左移动 和 竖直向下移动,注意动态规划的计算顺序
        for (int i = row - 1; i >= 0; i--) {
            for (int j = 0; j < col; j++) {
                if (i < row - 1) {
                    res[i][j] = Math.min(res[i][j], res[i + 1][j] + 1);
                }
                if (j > 0) {
                    res[i][j] = Math.min(res[i][j], res[i][j - 1] + 1);
                }
            }
        }
        // 只有 水平向右移动 和 竖直向上移动,注意动态规划的计算顺序
        for (int i = 0; i < row; i++) {
            for (int j = col - 1; j >= 0; j--) {
                if (i > 0) {
                    res[i][j] = Math.min(res[i][j], res[i - 1][j] + 1);
                }
                if (j < col - 1) {
                    res[i][j] = Math.min(res[i][j], res[i][j + 1] + 1);
                }
            }
        }
        // 只有 水平向右移动 和 竖直向下移动,注意动态规划的计算顺序
        for (int i = row - 1; i >= 0; i--) {
            for (int j = col - 1; j >= 0; j--) {
                if (i < row - 1) {
                    res[i][j] = Math.min(res[i][j], res[i + 1][j] + 1);
                }
                if (j < col - 1) {
                    res[i][j] = Math.min(res[i][j], res[i][j + 1] + 1);
                }
            }
        }
        return res;
    }
}
上一篇:解决方案-vector初始化后存放Mat,出现Mat矩阵数据同变问题


下一篇:leetcode 对角线遍历 中等