力扣994 腐烂的橘子DFS和BFS的不同


前言

深度优先搜索(DFS)和广度优先搜索(BFS)是图或树遍历中的两种经典算法,它们有不同的特点和应用场景。


深度优先搜索(DFS)

主要特点:
  1. 遍历顺序

    • DFS会沿着一条路径一直走到底,直到无法继续(即走到叶子节点或无未访问的邻居节点),然后回溯到最近的分叉点,尝试其他路径。
  2. 使用的数据结构

    • DFS通常使用来存储路径(可以使用递归隐式地利用系统栈)。
  3. 实现方式

    • DFS通常可以通过递归或显式栈来实现。
  4. 时间复杂度

    • 对于图,时间复杂度为 O(V + E),其中 V 是顶点数,E 是边数。对于树,时间复杂度为 O(n),n 是节点数量。
  5. 空间复杂度

    • 对于递归实现,空间复杂度取决于递归的深度。在最坏的情况下,递归的深度可以达到图的深度或树的高度。空间复杂度为 O(H),其中 H 是树的高度或图的最大深度。
  6. 适用场景

    • DFS适合用于寻找路径或需要深入探索所有分支的场景,如解决迷宫问题、图的连通性、拓扑排序等。

广度优先搜索(BFS)

主要特点:
  1. 遍历顺序

    • BFS按层次进行遍历,先访问离起始节点最近的节点,然后逐层向外扩展,直到所有节点都被访问。
  2. 使用的数据结构

    • BFS使用队列来存储待访问的节点,保证按层次顺序访问。
  3. 实现方式

    • BFS通常通过队列实现。
  4. 时间复杂度

    • 对于图,时间复杂度为 O(V + E),其中 V 是顶点数,E 是边数。对于树,时间复杂度为 O(n)。
  5. 空间复杂度

    • 需要存储每一层的节点,所以空间复杂度为 O(W),其中 W 是图或树的最大宽度(即一层中最多节点的数量)。
  6. 适用场景

    • BFS适合用于寻找最短路径或在分层结构中查找特定元素,如图的最短路径、迷宫最短路径问题等。

二、力扣994题腐烂橘子DFS和BFS代码

1.DFS

class Solution {
    int rl, cl, res;
    public int orangesRotting(int[][] grid) {
        int rl = grid.length, cl = grid[0].length, res = -1;
        for (int r = 0; r < rl; r ++) {
            for (int c = 0; c < cl; c ++) {
                if (grid[r][c] == 2) {
                    this.dfs(grid, r, c, 3);
                }
            }
        }

        for (int r = 0; r < rl; r ++) {
            for (int c = 0; c < cl; c ++) {
                if (grid[r][c] == 1) {
                    return -1;
                }
                res = Math.max(res, grid[r][c]);
            }
        }
        return res == 0 ? 0 : res - 2;
    }

    private void dfs(int[][] grid, int r, int c, int expect) {
        int rl = grid.length, cl = grid[0].length;
        if (r > 0 && (grid[r - 1][c] > expect || grid[r - 1][c] == 1)) {
            grid[r - 1][c] = expect;
            this.dfs(grid, r - 1, c, expect + 1);
        }
        if (r < rl - 1 && (grid[r + 1][c] > expect || grid[r + 1][c] == 1)) {
            grid[r + 1][c] = expect;
            this.dfs(grid, r + 1, c, expect + 1);
        }
        if (c > 0 && (grid[r][c - 1] > expect || grid[r][c - 1] == 1)) {
            grid[r][c - 1] = expect;
            this.dfs(grid, r, c - 1, expect + 1);
        }
        if (c < cl - 1 && (grid[r][c + 1] > expect || grid[r][c + 1] == 1)) {
            grid[r][c + 1] = expect;
            this.dfs(grid, r, c + 1, expect + 1);
        }
    }
}

2.BFS

class Solution {
    public int orangesRotting(int[][] grid) {
        if (grid == null || grid.length == 0)
            return -1;
        int row = grid.length;
        int col = grid[0].length;
        Queue<int[]> q = new LinkedList<>();
        int freashOrange = 0;
        for (int i = 0 ; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == 2) {
                    q.offer(new int[]{i, j});
                }
                if (grid[i][j] == 1)
                    freashOrange++;
            }
        }
        if (freashOrange == 0)
            return 0;
        int time = 0;
        int[][] directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
        while (!q.isEmpty()) {
            int size = q.size();
            boolean flag = false;
            for (int i = 0; i < size; i++) {
                int[] current = q.poll();
                int row2 = current[0];
                int col2 = current[1];
                for (int[] dierction : directions) {
                    int newrow = row2 + dierction[0];
                    int newcol = col2 + dierction[1];
                    if (newrow >= 0 && newrow < row && newcol >= 0 && newcol < col && grid[newrow][newcol] == 1) {
                        grid[newrow][newcol] = 2;
                        q.offer(new int[]{newrow, newcol});
                        freashOrange--;
                        flag = true;
                    }
                }
            }
            if (flag) {
                time++;
            }
        }
        return freashOrange == 0 ? time : -1;
    }
}

总结

DFS 在一些小规模输入下,或者在某些实现中,可能表现得比 BFS 快一些,这是因为 DFS 的递归实现更简洁,

    常数因子较小,栈操作的开销可能小于队列操作的开销。

    BFS 是更适合腐烂橘子问题的解决方案,因为它符合逐层扩散的自然过程,并且能够保证腐烂橘子传播到每个新鲜橘子的最短时间。

    因此,虽然 DFS 可能会在某些特定情况下表现得更快,但对于这道题,BFS 是更加直观、正确且鲁棒的选择。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值