• [LeetCode] 417. Pacific Atlantic Water Flow


    Given an m x n matrix of non-negative integers representing the height of each unit cell in a continent, the "Pacific ocean" touches the left and top edges of the matrix and the "Atlantic ocean" touches the right and bottom edges.

    Water can only flow in four directions (up, down, left, or right) from a cell to another one with height equal or lower.

    Find the list of grid coordinates where water can flow to both the Pacific and Atlantic ocean.

    Note:

    1. The order of returned grid coordinates does not matter.
    2. Both m and n are less than 150.

    Example:

    Given the following 5x5 matrix:
    
      Pacific ~   ~   ~   ~   ~ 
           ~  1   2   2   3  (5) *
           ~  3   2   3  (4) (4) *
           ~  2   4  (5)  3   1  *
           ~ (6) (7)  1   4   5  *
           ~ (5)  1   1   2   4  *
              *   *   *   *   * Atlantic
    
    Return:
    
    [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix).

    太平洋大西洋水流问题。给一个二维矩阵,矩阵里的数字表示水的高度。矩阵的边缘是太平洋和大西洋。水流遵循高处往低处流的原则,求这个矩阵里面哪些坐标上的水能同时流动到太平洋和大西洋。例子中所有带括号的坐标,最终都能流向两个海洋。

    这一题也属于flood fill类的题目。但是这个题的做法非常巧妙,可以试着从矩阵的边缘往中间找,看看最远能找到矩阵内的哪些坐标。这些被找到的坐标上的水一定能流到两个海洋里。比如左边缘和上边缘是太平洋,就可以找i == 0和j == 0的坐标去做DFS,并记录有哪些坐标能被遍历到。同理,右边缘和下边缘是大西洋,可以找i == m  - 1和j == n - 1的坐标去做DFS,并记录哪些坐标能被找到。在两次DFS中都被找到的坐标,则是可以同时流向两个大洋的。

    同时这一题在做DFS的时候,也跟329题类似,需要记录一个prev值,以判断当前坐标上的水的深度和之前遍历的坐标上的水的深度谁高谁低。

    时间O(mn)

    空间O(mn)

    Java实现

     1 class Solution {
     2     public List<List<Integer>> pacificAtlantic(int[][] matrix) {
     3         List<List<Integer>> res = new ArrayList<>();
     4         // corner case
     5         if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
     6             return res;
     7         }
     8 
     9         // normal case
    10         int m = matrix.length;
    11         int n = matrix[0].length;
    12         int[][] pacific = new int[m][n];
    13         int[][] atlantic = new int[m][n];
    14         // scan the edge
    15         for (int i = 0; i < m; i++) {
    16             for (int j = 0; j < n; j++) {
    17                 if (i == 0 || j == 0) {
    18                     dfs(matrix, pacific, i, j, matrix[i][j]);
    19                 }
    20                 if (i == m - 1 || j == n - 1) {
    21                     dfs(matrix, atlantic, i, j, matrix[i][j]);
    22                 }
    23             }
    24         }
    25 
    26         // the rest of the matrix
    27         for (int i = 0; i < m; i++) {
    28             for (int j = 0; j < n; j++) {
    29                 if (pacific[i][j] == 1 && atlantic[i][j] == 1) {
    30                     res.add(Arrays.asList(i, j));
    31                 }
    32             }
    33         }
    34         return res;
    35     }
    36 
    37     private void dfs(int[][] matrix, int[][] visited, int i, int j, int prevHeight) {
    38         // corner case
    39         if (i < 0 || j < 0 || i >= matrix.length || j >= matrix[0].length || visited[i][j] == 1
    40                 || matrix[i][j] < prevHeight) {
    41             return;
    42         }
    43         visited[i][j] = 1;
    44         dfs(matrix, visited, i - 1, j, matrix[i][j]);
    45         dfs(matrix, visited, i + 1, j, matrix[i][j]);
    46         dfs(matrix, visited, i, j - 1, matrix[i][j]);
    47         dfs(matrix, visited, i, j + 1, matrix[i][j]);
    48     }
    49 }

    flood fill题型总结

    LeetCode 题目总结

  • 相关阅读:
    css 让div居中的代码
    纯Css实现两个Div占满整屏高度
    .net core api开发之从Postman发请求,接收不到参数值的问题记录
    win10下 IIS提示 处理程序“ExtensionlessUrlHandlerIntegrated4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler”
    关于Linux fontconfig 字体库的坑
    前端性能优化方案,取自前端优化雅虎军规35条
    居中对齐
    sticky footer布局
    第30天 [js]写一个方法判断字符串是否为回文字符串
    第46天 [js] 写一个使两个整数进行交换的方法(不能使用临时变量)
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13364154.html
Copyright © 2020-2023  润新知