leetcode 算法入门 第九天深搜/广搜

这篇博客介绍了如何使用动态规划(DP)和广度优先搜索(BFS)解决LeetCode上的两道题目:542.01矩阵和994.腐烂的橘子。对于01矩阵问题,通过两次遍历实现了从1到0的距离更新;而对于腐烂的橘子,利用BFS从腐烂的橘子开始传播,计算出全部变为腐烂状态所需的最短时间。
摘要由CSDN通过智能技术生成

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值