zoukankan      html  css  js  c++  java
  • [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 题目总结

  • 相关阅读:
    安装Rocky版OpenStack 1控制节点+1计算节点环境部署脚本
    脚本安装Rocky版OpenStack 1控制节点+1计算节点环境部署
    采用脚本自动填写具有交互式命令的方法
    CentOS安装Docker
    WordPress博客搭建与问题总结
    OpenStack端口(15)
    openstack搭建之-horizon配置(14)
    openstack搭建之-创建实例(13)
    openstack搭建之-cinder配置(12)
    openstack搭建之-neutron配置(11)
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13364154.html
Copyright © 2011-2022 走看看