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).

这道题给了我们一个二维数组,说是数组的左边和上边是太平洋,右边和下边是大西洋,假设水能从高处向低处流,问我们所有能流向两大洋的点的集合。刚开始博主没有理解题意,以为加括号的点是一条路径,连通两大洋的,但是看来看去感觉也不太对,后来终于明白了,是每一个点单独都有路径来通向两大洋。那么就是典型的搜索问题,我最开始想的是对于每个点都来搜索是否能到达边缘,只不过搜索的目标点不再是一个单点,而是所有的边缘点,照这种思路写出的代码无法通过 OJ 大数据集,那么就要想办法来优化代码,优化的方法跟之前那道 Surrounded Regions 很类似,都是换一个方向考虑问题,既然从每个点向中间扩散会 TLE,那么我们就把所有边缘点当作起点开始遍历搜索,然后标记能到达的点为 true,分别标记出 pacific 和 atlantic 能到达的点,那么最终能返回的点就是二者均为 true 的点。我们可以先用DFS来遍历二维数组,参见代码如下:

解法一:

class Solution {
public:
vector<pair<int, int>> pacificAtlantic(vector<vector<int>>& matrix) {
if (matrix.empty() || matrix[].empty()) return {};
vector<pair<int, int>> res;
int m = matrix.size(), n = matrix[].size();
vector<vector<bool>> pacific(m, vector<bool>(n, false));
vector<vector<bool>> atlantic(m, vector<bool>(n, false));
for (int i = ; i < m; ++i) {
dfs(matrix, pacific, INT_MIN, i, );
dfs(matrix, atlantic, INT_MIN, i, n - );
}
for (int i = ; i < n; ++i) {
dfs(matrix, pacific, INT_MIN, , i);
dfs(matrix, atlantic, INT_MIN, m - , i);
}
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (pacific[i][j] && atlantic[i][j]) {
res.push_back({i, j});
}
}
}
return res;
}
void dfs(vector<vector<int>>& matrix, vector<vector<bool>>& visited, int pre, int i, int j) {
int m = matrix.size(), n = matrix[].size();
if (i < || i >= m || j < || j >= n || visited[i][j] || matrix[i][j] < pre) return;
visited[i][j] = true;
dfs(matrix, visited, matrix[i][j], i + , j);
dfs(matrix, visited, matrix[i][j], i - , j);
dfs(matrix, visited, matrix[i][j], i, j + );
dfs(matrix, visited, matrix[i][j], i, j - );
}
};

那么 BFS 的解法也可以做,用 queue 来辅助,开始把边上的点分别存入 queue 中,然后对应的 map 标记 true,然后开始 BFS 遍历,遍历结束后还是找 pacific 和 atlantic 均标记为 true 的点加入结果 res 中返回即可,参见代码如下:

解法二:

class Solution {
public:
vector<pair<int, int>> pacificAtlantic(vector<vector<int>>& matrix) {
if (matrix.empty() || matrix[].empty()) return {};
vector<pair<int, int>> res;
int m = matrix.size(), n = matrix[].size();
queue<pair<int, int>> q1, q2;
vector<vector<bool>> pacific(m, vector<bool>(n, false)), atlantic = pacific;
for (int i = ; i < m; ++i) {
q1.push({i, });
q2.push({i, n - });
pacific[i][] = true;
atlantic[i][n - ] = true;
}
for (int i = ; i < n; ++i) {
q1.push({, i});
q2.push({m - , i});
pacific[][i] = true;
atlantic[m - ][i] = true;
}
bfs(matrix, pacific, q1);
bfs(matrix, atlantic, q2);
for (int i = ; i < m; ++i) {
for (int j = ; j < n; ++j) {
if (pacific[i][j] && atlantic[i][j]) {
res.push_back({i, j});
}
}
}
return res;
}
void bfs(vector<vector<int>>& matrix, vector<vector<bool>>& visited, queue<pair<int, int>>& q) {
int m = matrix.size(), n = matrix[].size();
vector<vector<int>> dirs{{,-},{-,},{,},{,}};
while (!q.empty()) {
auto t = q.front(); q.pop();
for (auto dir : dirs) {
int x = t.first + dir[], y = t.second + dir[];
if (x < || x >= m || y < || y >= n || visited[x][y] || matrix[x][y] < matrix[t.first][t.second]) continue;
visited[x][y] = true;
q.push({x, y});
}
}
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/417

参考资料:

https://leetcode.com/problems/pacific-atlantic-water-flow/

https://leetcode.com/problems/pacific-atlantic-water-flow/discuss/90733/java-bfs-dfs-from-ocean

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Pacific Atlantic Water Flow 太平洋大西洋水流的更多相关文章

  1. [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 contin ...

  2. 417 Pacific Atlantic Water Flow 太平洋大西洋水流

    详见:https://leetcode.com/problems/pacific-atlantic-water-flow/description/ C++: class Solution { publ ...

  3. Leetcode: Pacific Atlantic Water Flow

    Given an m x n matrix of non-negative integers representing the height of each unit cell in a contin ...

  4. [LeetCode] Pacific Atlantic Water Flow 题解

    题意 题目 思路 一开始想用双向广搜来做,找他们相碰的点,但是发现对其的理解还是不够完全,导致没写成功.不过,后来想清楚了,之前的错误可能在于从边界点进行BFS,其访问顺序应该是找到下一个比当前那个要 ...

  5. [Swift]LeetCode417. 太平洋大西洋水流问题 | Pacific Atlantic Water Flow

    Given an m x n matrix of non-negative integers representing the height of each unit cell in a contin ...

  6. 【LeetCode】417. Pacific Atlantic Water Flow 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/pacific- ...

  7. LeetCode 417. Pacific Atlantic Water Flow

    原题链接在这里:https://leetcode.com/problems/pacific-atlantic-water-flow/description/ 题目: Given an m x n ma ...

  8. 417. Pacific Atlantic Water Flow

    正常做的,用了645MS..感觉DFS的时候剪枝有问题.. 为了剪枝可能需要标记一个点的4种情况: 1:滨临大西洋,所有太平洋来的点可以通过: 2:濒临太平洋,所有大西洋来的点可以通过: 3:都不濒临 ...

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

    太平洋大西洋水流问题 给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度."太平洋"处于大陆的左边界和上边界,而"大西洋"处于大陆的右边界和下 ...

随机推荐

  1. github常见问题【转自百度知道】

    1 git config --global user.name "Your Real Name" 2 git config --global user.email you@emai ...

  2. 用github来展示你的前端页面吧

    前言 经常会有人问我如何才能将自己做的静态页面放到网上供他人欣赏,是不是需要自己有一个服务器,是不是还要搞个域名才能访问?对于以上问题我都会回答:用github来展示你的前端页面吧. 工欲善其事,必先 ...

  3. iOS 编辑UITableView(根据iOS编程编写)

    上个项目我们完成了 JXHomepwner 简单的应用展示,项目地址.本节我们需要在上节项目基础上,增加一些响应用户操作.包括添加,删除和移动表格. 编辑模式 UITableView 有一个名为  e ...

  4. Basic Tutorials of Redis(5) - Sorted Set

    The last post is mainly about the unsorted set,in this post I will show you the sorted set playing a ...

  5. 实现对gridview删除行时弹出确认对话框的一种简单方法

    在VS2008提供的GridView中我们可以直接添加一个CommandField删除列:<asp:CommandField ShowDeleteButton="True" ...

  6. input输入

    只能输入数字onkeyup='this.value=this.value.replace(/\D/gi,"")'限制文本框只能输入正数,小数onkeyup="value= ...

  7. 2016年最新mac下vscode配置golang开发环境支持debug

    网上目前还找不到完整的mac下golang环境配置支持,本人配置成功,现在整理分享出来. mac最好装下xcode,好像有依赖关系安装Homebrew打开终端窗口, 粘贴脚本执行/usr/bin/ru ...

  8. A2W、W2A、A2T、T2A的使用方法

    1.A2W和W2A 在<Window核心编程>,多字节和宽字节之间转换比较麻烦的,MultiByteToWideChar函数和WideCharToMultiByte函数有足够多的参数的意义 ...

  9. jQuery 中bind(),live(),delegate(),on() 区别(转)

    当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...

  10. react-echarts之折线图的显示

    react中想要实现折线图和饼图的功能,需要引入react-echarts包,然后再实现折线图的功能.我这里引用的版本是:0.1.1.其他的写法参echarts官网即可.下面详细讲解的是我在react ...