0
点赞
收藏
分享

微信扫一扫

[LeetCode]-5-DFS

LeetCode-DFS

DFS,Depth First Search,深度优先搜索,是图论中一个遍历搜索算法

200.岛屿数量

在刚开始学习数据结构图论中的DFS时,是使用邻接数组存储结构,借助visited数组标记某个顶点是否被访问过,然后对图中每一个未被访问的节点进行DFS深度优先遍历,每遍历到一个顶点就标记该节点被访问,当所有顶点均被访问,即visited数组中所有元素值都为1时,遍历结束
而在实际解题应用中,有时候可以不用借助visited数组来达到标记被访问的效果,节省空间。例如这道题中,题目说到岛屿总是被水包围,所以只要遍历到了"1",说明一定会对应地存在一个岛屿,那么跟这个"1"在同一个岛屿上的其它"1"就不需要被遍历了,所以对这个"1"进行DFS将与其在同一个岛屿上的“1”改为"0"即可,后续就不会再对那些点进行遍历,达到标记的目的

public int numIslands(char[][] grid) {
    int res = 0;
    for(int i = 0;i < grid.length;i++){
        for(int j = 0;j < grid[0].length;j++){
            if(grid[i][j] == '1'){
                res++;
                dfs(grid,i,j);
            }
        }
    }
    return res;
}
public void dfs(char[][] grid,int i,int j){
	//递归边界 : 索引越界或遍历到了"0"
    if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') return;
    //标记为"0"
    grid[i][j] = '0';
    //根据"每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成",对上下左右的相邻顶点进行dfs
    dfs(grid,i - 1,j);
    dfs(grid,i + 1,j);
    dfs(grid,i,j + 1);
    dfs(grid,i,j - 1);
}

1254.统计封闭岛屿的数量

从题意可以看出,只要存在在矩阵的四条边上的土地的岛屿都不是封闭岛屿,那么继续沿用上面200题的思想解题,而不同的地方在于,要先把矩阵四条边上的土地所在的岛屿先置为"1",变为水,然后再对剩下的区域进行查找岛屿数量的操作

public int closedIsland(int[][] grid) {
    int row = grid.length;
    int column = grid[0].length;
    int res = 0;
    //先排除掉四条边上的岛屿
    for(int i = 0;i < row;i++){
        dfs(grid,i,0);
        dfs(grid,i,column - 1);
    }
    for(int i = 0;i < column;i++){
        dfs(grid,0,i);
        dfs(grid,row - 1,i);
    }
    //再进行200题的查找岛屿数量操作
    for(int i = 0;i < row;i++){
        for(int j = 0;j < column;j++){
            if(grid[i][j] == 0){
                res++;
                dfs(grid,i,j);
            }
        }
    }
    return res;
}
public void dfs(int[][] grid,int i,int j){
    if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 1) return;
    grid[i][j] = 1;
    dfs(grid,i - 1,j);
    dfs(grid,i + 1,j);
    dfs(grid,i,j + 1);
    dfs(grid,i,j - 1);
}

695.岛屿的最大面积

同样的,继续沿用200的做法,而不同的地方在于,找出岛屿的同时还要记录岛屿的面积,即土地数,所以要把dfs方法改为能计算岛屿面积的方法

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++){
            if(grid[i][j] == 1){
            	//与200题相比,不是每dfs一个岛屿就记录一个数量,
            	//而是通过dfs得到岛屿的面积然后记录最大的面积
                res = Math.max(res,dfs(grid,i,j));
            }
        }
    }
    return res;
}
public int dfs(int[][] grid,int i,int j){
    if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) return 0;
    grid[i][j] = 0;
    //递归的思路:要求当前土地(i,j)所在的岛屿的面积,则等于1加上下左右相邻土地的总面积
    return 1 + dfs(grid,i - 1,j) +
               dfs(grid,i + 1,j) +
               dfs(grid,i,j + 1) +
               dfs(grid,i,j - 1);
}

1020.飞地的数量

这道题结合了1254题跟695题,要先像695题一样排除掉边界的岛屿,然后统计剩下的所有符合"飞地"条件的岛屿的单元格的总数量

public int numEnclaves(int[][] grid) {
    int row = grid.length;
    int column = grid[0].length;
    int res = 0;
    for(int i = 0;i < row;i++){
        dfs(grid,i,0);
        dfs(grid,i,column - 1);
    }
    for(int i = 0;i < column;i++){
        dfs(grid,0,i);
        dfs(grid,row - 1,i);
    }
    for(int i = 0;i < row;i++){
        for(int j = 0;j < column;j++){
            if(grid[i][j] == 1){
            	//计算每个“飞地“的面积,即单元格数量,然后叠加得到最终的总单元格数量
                res += dfs(grid,i,j);
            }
        }
    }
    return res;
}
//统计一个岛屿上的单元格的数量,即一个岛屿的面积
public int dfs(int[][] grid,int i,int j){
    if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) return 0;
    grid[i][j] = 0;
    return 1 + dfs(grid,i - 1,j) +
            dfs(grid,i + 1,j) +
            dfs(grid,i,j + 1) +
            dfs(grid,i,j - 1);
}

1905.统计子岛屿

题目要求子岛屿的数量,那就先把grid2中不符合子岛屿条件的岛屿先“淹没掉”,即都变成“0“,那么剩下的岛屿就都是子岛屿了,再进行统计岛屿数量的操作就可以了

public int countSubIslands(int[][] grid1, int[][] grid2) {
    int row = grid2.length;
    int column = grid2[0].length;
    for(int  i = 0;i < row;i++){
        for(int j = 0;j < column;j++){
        	//先排除掉不符合子岛屿条件的岛屿
            if(grid2[i][j] == 1 && grid1[i][j] == 0){
                dfs(grid2,i,j);
            }
        }
    }
    //像200题一样统计岛屿数量
    int res = 0;
    for(int  i = 0;i < row;i++){
        for(int j = 0;j < column;j++){
            if(grid2[i][j] == 1){
                res++;
                dfs(grid2,i,j);
            }
        }
    }
    return res;
}
public void dfs(int[][] grid,int i,int j){
    if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) return;
    grid[i][j] = 0;
    dfs(grid,i - 1,j);
    dfs(grid,i + 1,j);
    dfs(grid,i,j + 1);
    dfs(grid,i,j - 1);
}
举报

相关推荐

0 条评论