zoukankan      html  css  js  c++  java
  • LeetCode417. 太平洋大西洋水流问题

    ☆☆☆思路:类似于130题。从边界开始扩展。

      建立两个矩阵Atlantic和Pacific, 当Atlantic[i][j]和Pacific[i][j]同时为true时表示该位置可以同时到达Atlantic和Pacific

      遍历时的技巧为: 只需要从四个边界开始遍历即可(类似Flood Fill的思想, 只要可以从边界出发到达, 就说明该位置的水可以流向对应的海洋)

    class Solution {
        public List<List<Integer>> pacificAtlantic(int[][] matrix) {
            List<List<Integer>> res = new ArrayList<>();
            if (matrix == null || matrix.length == 0) return res;
            int m = matrix.length, n = matrix[0].length;
            boolean[][] pacific = new boolean[m][n];  // 太平洋 (左 + 上)
            boolean[][] atlantic = new boolean[m][n]; // 大西洋 (右 + 下)
    
            // 第一列 和 最后一列
            for (int i = 0; i < m; i++) {
    //            dfs(matrix, i, 0, pacific, matrix[i][0]); ////            dfs(matrix, i, n-1, atlantic, matrix[i][n-1]); //
                dfs1(matrix, i, 0, pacific); //
                dfs1(matrix, i, n-1, atlantic); //
            }
            // 第一行 和 最后一行
            for (int i = 0; i < n; i++) {
    //            dfs(matrix, 0, i, pacific, matrix[0][i]); ////            dfs(matrix, m-1, i, atlantic, matrix[m-1][i]); //
                dfs1(matrix, 0, i, pacific); //
                dfs1(matrix, m-1, i, atlantic); //
            }
            // 当atlantic和pacific同时为true时表示该位置可以同时到达Atlantic和Pacific
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (pacific[i][j] && atlantic[i][j]) {
                        res.add(Arrays.asList(i, j));
                    }
                }
            }
            return res;
        }
        // FloodFill算法 —— 写法1, 需要记录前一个值pre
        private void dfs(int[][] matrix, int x, int y, boolean[][] visited, int pre) {
            // 越界判断 以及 是否访问过 判断
            if (x < 0 || x >= matrix.length || y < 0 || y >= matrix[0].length || visited[x][y]) return;
            if (matrix[x][y] < pre) return; // 必须逆流而上
            visited[x][y] = true;
            dfs(matrix, x - 1, y, visited, matrix[x][y]);
            dfs(matrix, x, y + 1, visited, matrix[x][y]);
            dfs(matrix, x + 1, y, visited, matrix[x][y]);
            dfs(matrix, x, y - 1, visited, matrix[x][y]);
        }
    
        // FloodFill算法 —— 写法2
        int[][] d = new int[][]{ {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; // 方向顺序不重要
        private boolean isArea(int[][] matrix, int x, int y) {
            return x >= 0 && x < matrix.length && y >= 0 && y < matrix[0].length;
        }
        private void dfs1(int[][] matrix, int x, int y, boolean[][] visited) {
            visited[x][y] = true;
            for (int i = 0; i < 4; i++) {
                int newx = x + d[i][0];
                int newy = y + d[i][1];
                if (isArea(matrix, newx, newy) && !visited[newx][newy] && matrix[newx][newy] >= matrix[x][y]) {
                    dfs1(matrix, newx, newy, visited);
                }
            }
        }
    }
  • 相关阅读:
    Ubuntu 32下Android NDK+NEON的配置过程及简单使用举例
    java环境变量配置
    实现TextView 文字排版,分散两端对齐
    cmd 控制台 提示:请求的操作须要提升!
    怎样将程序猿写出来的程序打包成安装包(最简单的)
    二分查找
    32位Linux文件限制大小
    Windows ICS 服务无法启动问题解决
    Microsoft.AlphaImageLoader滤镜解说
    memset函数具体说明
  • 原文地址:https://www.cnblogs.com/HuangYJ/p/14205889.html
Copyright © 2011-2022 走看看