17.关于BFS和DFS力扣算法刷题

2.力扣第733题图像渲染

17.关于BFS和DFS力扣算法刷题_第1张图片
17.关于BFS和DFS力扣算法刷题_第2张图片

  • DFS解法
class Solution {
    int[] dx = {1,0,0,-1};
    int[] dy = {0,1,-1,0};
    public int[][] floodFill(int[][] image, int sr, int sc, int color) {
        int currentColor = image[sr][sc];
        if(currentColor != color) {
            dfs(image,sr,sc,currentColor,color);
        }
        return image;
    }
    public void dfs(int[][] image,int x,int y,int currentColor,int color) {
        if(image[x][y] == currentColor) {
            image[x][y] = color;
            for(int i=0;i<4;i++) {
                int mx = x + dx[i];
                int my = y + dy[i];
                if(mx >= 0 && mx < image.length && my >= 0 && my < image[0].length) {
                    dfs(image,mx,my,currentColor,color);
                }
            }
        }
    }
}
  • BFS解法
在这里插入代码片

力扣695题岛屿的最大面积

17.关于BFS和DFS力扣算法刷题_第3张图片
17.关于BFS和DFS力扣算法刷题_第4张图片

  • DFS解法
class Solution {
    int[] dx = {1,0,0,-1};
    int[] dy = {0,1,-1,0};
    public int maxAreaOfIsland(int[][] grid) {
        int res = 0;
        for(int i=0;i<grid.length;i++) {
            for(int j=0;j<grid[0].length;j++) {
                res = Math.max(res,dfs(grid,i,j));
            }
        }
        return res;
    }
    private int dfs(int[][] grid,int x,int y) {
        if(x < 0 || y < 0 || x >= grid.length || y >= grid[0].length || grid[x][y] == 0) {
            return 0;
        }
        int num = 1;
        grid[x][y] = 0;
        for(int i=0;i<4;i++) {
            int mx = x + dx[i];
            int my = y + dy[i];
            if(mx >= 0 && mx < grid.length && my >= 0 && my < grid[0].length) {
                num += dfs(grid,mx,my);
            }
        }
        return num;
    }
}

200. 岛屿数量

17.关于BFS和DFS力扣算法刷题_第5张图片
17.关于BFS和DFS力扣算法刷题_第6张图片
DFS解法

class Solution {
    int[] dx = {1,0,0,-1};
    int[] dy = {0,1,-1,0};
    public int numIslands(char[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int num_islands = 0;
        for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                if(grid[i][j] == '1') {
                    num_islands++;
                    dfs(grid,i,j);
                }
            }
        }
        return num_islands;
    }
    public void dfs(char[][] grid,int x,int y) {
        if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == '0') {
            return;
        }
        grid[x][y] = '0';
        for(int i=0;i<4;i++) {
            int mx = x + dx[i];
            int my = y + dy[i];
            if(mx >= 0 && mx < grid.length && my >= 0 && my < grid[0].length && grid[mx][my] != '0') {
                dfs(grid,mx,my);
            }
        }
    }
}

1254. 统计封闭岛屿的数目

17.关于BFS和DFS力扣算法刷题_第7张图片

该道题与第200题岛屿数目十分相似,唯一不同的就是边界的处理,在该道题中,边界的陆地并不能被称为封闭岛屿,所以首先先对边界的行和列进行处理。

DFS解法

class Solution {
    int[] dx = {-1,0,0,1};
    int[] dy = {0,-1,1,0};
    public int closedIsland(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        //先从边界开始对陆地进行DFS搜索并将陆地标记为2
        //先对第一列和最后一列进行DFS
        for(int i=0;i<m;i++) {
            dfs(grid,i,0);
            dfs(grid,i,n-1);
        }
        //再对第一行和最后一行进行DFS搜索并将陆地标记为2
        for(int j=0;j<n;j++) {
            dfs(grid,0,j);
            dfs(grid,m-1,j);
        }
        int res = 0;
        for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                if(grid[i][j] == 0) {
                    res++;
                    dfs(grid,i,j);
                }
            }
        }
        return res;
    }
    public void dfs(int[][] grid,int x,int y) {
        if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == 1 || grid[x][y] == 2) {
            return;
        }
        grid[x][y] = 2;
        for(int i=0;i<4;i++) {
            int mx = x + dx[i];
            int my = y + dy[i];
            dfs(grid,mx,my);
        }
    }
}

1905.统计子岛屿

17.关于BFS和DFS力扣算法刷题_第8张图片

这道题与上面的那道题也有相似之处,首先先使用一次DFS算法,将不符合条件的陆地改为水域,然后再使用一次和上面相同的DFS算法对grid2中的陆地进行统计。

class Solution {
    int[] dx = {-1,0,0,1};
    int[] dy = {0,-1,1,0};
    public int countSubIslands(int[][] grid1, int[][] grid2) {
        int m = grid2.length;
        int n = grid2[0].length;
        for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                if(grid2[i][j] == 1 && grid1[i][j] != 1) {
                    dfs(grid2,i,j);
                }
            }
        }
        int res = 0;
        for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                if(grid2[i][j] == 1) {
                    res++;
                    dfs(grid2,i,j);
                }
            }
        }
        return res;
    }
    public void dfs(int[][] grid2,int x,int y) {
        if(x < 0 || x >= grid2.length || y < 0 || y >= grid2[0].length || grid2[x][y] == 0) {
            return;
        }
        grid2[x][y] = 0;
        for(int i=0;i<4;i++) {
            int mx = x + dx[i];
            int my = y + dy[i];
            dfs(grid2,mx,my);
        }
    }
}



130.被围绕的区域

17.关于BFS和DFS力扣算法刷题_第9张图片

class Solution {
    int[] dx = {-1,0,0,1};
    int[] dy = {0,-1,1,0};
    public void solve(char[][] board) {
        int m = board.length;
        int n = board[0].length;
        //首先先对第一列和最后一列进行dfs
        for(int i=0;i<m;i++) {
            if(board[i][0] == 'O') {
                dfs(board,i,0);
            }
            if(board[i][n-1] == 'O') {
                dfs(board,i,n-1);
            }
        }
        //其次对第一行和最后一行进行dfs
        for(int j=0;j<n;j++) {
            if(board[0][j] == 'O') {
                dfs(board,0,j);
            }
            if(board[m-1][j] == 'O') {
                dfs(board,m-1,j);
            }
        }
        for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                if(board[i][j] == 'F') {
                    board[i][j] = 'O';
                }else if(board[i][j] == 'O') {
                    board[i][j] = 'X';
                }
            }
        }
    }
    public void dfs(char[][] board,int x,int y) {
        if(x < 0 || x >= board.length || y < 0 || y >= board[0].length || board[x][y] != 'O') {
            return;
        }
        board[x][y] = 'F';
        for(int i=0;i<4;i++) {
            int mx = x + dx[i];
            int my = y + dy[i];
            dfs(board,mx,my);
        }
    }
}




463. 岛屿的周长

17.关于BFS和DFS力扣算法刷题_第10张图片
17.关于BFS和DFS力扣算法刷题_第11张图片

class Solution {
    int[] dx = {-1,0,0,1};
    int[] dy = {0,1,-1,0};
    public int islandPerimeter(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int res = 0;
        for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                if(grid[i][j] == 1) {
                    res += dfs(grid,i,j);
                }
            }
        }
        return res;
    }
    public int dfs(int[][] grid,int x,int y) {
        if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == 0) {
            return 1;
        }
        if(grid[x][y] == 2) {
            return 0;
        }
        grid[x][y] = 2;
        int res = 0;
        for(int i=0;i<4;i++) {
            int mx = x + dx[i];
            int my = y + dy[i];
            res += dfs(grid,mx,my);
        }
        return res;
    }
}

417.太平洋大西洋水流问题

17.关于BFS和DFS力扣算法刷题_第12张图片
17.关于BFS和DFS力扣算法刷题_第13张图片

  • 这个题目可以借鉴「被围绕的区域」的思路,从四个边入手。「被围绕的区域」中判断与岸边相连是通过相连格子是否等于O,而我们判断与边相连需要通过高度,只有当前格子比前一格子高时才可以保证水可以流入Ocean
  • 还需要注意的一个点,「被围绕的区域」中直接给访问过的格子赋了新的值,可以通过新值判断是否已经访问过;但是本题中是没有改变格子原有的值,所以需要visited[][]来记录访问情况
  • 我们分成两部分,首先求出可以流入 Pacific Ocean 的格子,然后求出可以流入 Atlantic Ocean的格子,这两部分格子的重叠部分就是题目的答案
class Solution {
    int[] dx = {-1,0,0,1};
    int[] dy = {0,-1,1,0};
    public List<List<Integer>> pacificAtlantic(int[][] heights) {
        int m = heights.length;
        int n = heights[0].length;
        //定义访问数组
        boolean[][] po = new boolean[m][n];
        boolean[][] ao = new boolean[m][n];
        //首先先对第一列和最后一列进行dfs
        for(int i=0;i<m;i++) {
            dfs(heights,i,0,po,heights[i][0]);
            dfs(heights,i,n-1,ao,heights[i][n-1]);
        }
        //其次对第一行和最后一行进行dfs
        for(int j=0;j<n;j++) {
            dfs(heights,0,j,po,heights[0][j]);
            dfs(heights,m-1,j,ao,heights[m-1][j]);
        }
        List<List<Integer>> res = new ArrayList<>();
        //最后对其进行取交集
        for(int i=0;i<m;i++) {
            for(int j=0;j<n;j++) {
                if(po[i][j] == true && ao[i][j] == true) {
                    res.add(Arrays.asList(i,j));
                }
            }
        }
        return res;
    }
    public void dfs(int[][] heights,int x,int y,boolean[][] visit,int pre) {
        int m = heights.length;
        int n = heights[0].length;
        if(x < 0 || x >= m || y < 0 || y >= n || visit[x][y] || pre > heights[x][y]) {
            return;
        }
        visit[x][y] = true;
        for(int i=0;i<4;i++) {
            int mx = x + dx[i];
            int my = y + dy[i];
            dfs(heights,mx,my,visit,heights[x][y]);
        }
    }
}



你可能感兴趣的:(LeetCode算法刷题,算法,深度优先,宽度优先)