Day33|1020. 飞地的数量,130. 被围绕的区域,417. 太平洋大西洋水流问题

1020. 飞地的数量

代码随想录

先淹掉例外情况,再dfs统计

class Solution {
    int res = 0;
    public int numEnclaves(int[][] grid) {
        for(int i = 0; i < grid.length; i++){
            if(grid[i][0] == 1){
                dfs(grid, i, 0);
            }
            if(grid[i][grid[0].length - 1] == 1){
                dfs(grid, i, grid[0].length - 1);
            }
        }
        for(int j = 0; j < grid[0].length; j++){
            if(grid[0][j] == 1){
                dfs(grid, 0, j);
            }
            if(grid[grid.length - 1][j] == 1){
                dfs(grid, grid.length - 1, j);
            }
        }
        res = 0;
        

        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid[0].length; j++){
                if(grid[i][j] == 1){
                    dfs(grid, i, j);
                }
            }
        }
        return res;
    }
    void dfs(int[][] grid, int r, int c){
        
        if(r >= grid.length || r < 0 || c >= grid[0].length || c < 0){
            return;
        }
        if(grid[r][c] == 0){
            return;
        }
        res++;
        grid[r][c] = 0;
        
        
        dfs(grid, r + 1, c);
        dfs(grid, r, c + 1);
        dfs(grid, r - 1, c);
        dfs(grid, r, c - 1);

    }
}

130. 被围绕的区域

代码随想录

把边界上的岛屿标记成A,内部岛屿标记成O,先把内部岛屿标记成X,再把A岛屿恢复成O

class Solution {
    public void solve(char[][] board) {
        for(int i = 0; i < board.length; i++){
            if(board[i][0] == 'O'){
                dfs(board, i, 0);
            }
            if(board[i][board[0].length - 1] == 'O'){
                dfs(board, i, board[0].length - 1);
            }
        }
        for(int j = 0; j < board[0].length; j++){
            if(board[0][j] == 'O'){
                dfs(board, 0, j);
            }
            if(board[board.length - 1][j] == 'O'){
                dfs(board, board.length - 1, j);
            }
        }
        for(int i = 0; i < board.length; i++){
            for(int j = 0; j < board[0].length; j++){
                //这两句置换的顺序很讲究,颠倒了'O'就全变成'X'了
                if(board[i][j] == 'O'){
                    board[i][j] = 'X';
                }

                if(board[i][j] == 'A'){
                    board[i][j] = 'O';
                }
            }
        }
    }

    void dfs(char[][] board, int r, int c){

        if(r < 0 || c < 0 || r >= board.length || c >= board[0].length){
            return;
        }
        if(board[r][c] != 'O'){
            return;
        }
        board[r][c] = 'A';

        dfs(board, r + 1, c);
        dfs(board, r, c + 1);
        dfs(board, r - 1, c);
        dfs(board, r, c - 1);
    }
}

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

代码随想录

用for循环写横向需要先行检验参数合法性,

手动输入横向,只需在dfs内部检验参数合法性即可

for横向如果用return结束会导致整个横向终结,出现少遍历的情况,

手动横向,不好在上下层参数之间作比较,比如

if(heights[nextr][nextc] < heights[r][c]){
                continue;
            }

两种方式其实熟练起来for横向更简单?

class Solution {
    int[][] dir = {{1,0},{0,1},{-1,0},{0,-1}};
    public List<List<Integer>> pacificAtlantic(int[][] heights) {
        boolean[][] Pacific = new boolean[heights.length][heights[0].length];
        boolean[][] Atlantic = new boolean[heights.length][heights[0].length];
        ArrayList<Integer> path = new ArrayList<>();
        List<List<Integer>> res = new ArrayList<>();

        for(int i = 0; i < heights.length; i++){
            dfs(heights, Pacific, i, 0);
            dfs(heights, Atlantic, i, heights[0].length - 1);
        }

        for(int j = 0; j < heights[0].length; j++){
            dfs(heights, Pacific, 0, j);
            dfs(heights, Atlantic, heights.length - 1, j);
        }

        for(int i = 0; i < heights.length; i++){
            for(int j = 0; j < heights[0].length; j++){
                if(Pacific[i][j] == true && Atlantic[i][j] == true){
                    path.add(i);
                    path.add(j);
                    res.add(new ArrayList<>(path));
                    path.remove(path.size() - 1);
                    path.remove(path.size() - 1);
                }
            }
        }
        return res;
    }

    void dfs(int[][] heights, boolean[][] visited, int r, int c){
        if(visited[r][c] == true){
            return;
        }
        visited[r][c] = true;
        for(int i = 0; i < 4; i++){
            int nextr = r + dir[i][0];
            int nextc = c + dir[i][1];
            if(nextr < 0 || nextc < 0 || nextr >= heights.length || nextc >= heights[0].length){
                continue;
            }
            if(heights[nextr][nextc] < heights[r][c]){
                continue;
            }
            dfs(heights, visited, nextr, nextc);   
        }
        return;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值