[LeetCode] 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:
- The order of returned grid coordinates does not matter.
- 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 太平洋大西洋水流的更多相关文章
- [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 ...
- 417 Pacific Atlantic Water Flow 太平洋大西洋水流
详见:https://leetcode.com/problems/pacific-atlantic-water-flow/description/ C++: class Solution { publ ...
- 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 ...
- [LeetCode] Pacific Atlantic Water Flow 题解
题意 题目 思路 一开始想用双向广搜来做,找他们相碰的点,但是发现对其的理解还是不够完全,导致没写成功.不过,后来想清楚了,之前的错误可能在于从边界点进行BFS,其访问顺序应该是找到下一个比当前那个要 ...
- [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 ...
- 【LeetCode】417. Pacific Atlantic Water Flow 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/pacific- ...
- LeetCode 417. Pacific Atlantic Water Flow
原题链接在这里:https://leetcode.com/problems/pacific-atlantic-water-flow/description/ 题目: Given an m x n ma ...
- 417. Pacific Atlantic Water Flow
正常做的,用了645MS..感觉DFS的时候剪枝有问题.. 为了剪枝可能需要标记一个点的4种情况: 1:滨临大西洋,所有太平洋来的点可以通过: 2:濒临太平洋,所有大西洋来的点可以通过: 3:都不濒临 ...
- Leetcode 417.太平洋大西洋水流问题
太平洋大西洋水流问题 给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度."太平洋"处于大陆的左边界和上边界,而"大西洋"处于大陆的右边界和下 ...
随机推荐
- 【分布式】Zookeeper与Paxos
一.前言 在学习了Paxos在Chubby中的应用后,接下来学习Paxos在开源软件Zookeeper中的应用. 二.Zookeeper Zookeeper是一个开源的分布式协调服务,其设计目标是将那 ...
- 嵌入式开发中常见3个的C语言技巧
Hey,大家好!我是CrazyCatJack.今天我来说几个在嵌入式开发中常用的C语言技巧吧.也许你曾经用过,也许你只是见到过但是没有深入理解.那么今天好好补充下吧^_^ 1.指向函数的指针 指针不光 ...
- asp.net core 依赖注入问题
最近.net core可以跨平台了,这是一个伟大的事情,为了可以赶上两年以后的跨平台部署大潮,我也加入到了学习之列.今天研究的是依赖注入,但是我发现一个问题,困扰我很久,现在我贴出来,希望可以有人帮忙 ...
- Dapper-据说stackoverflow使用的orm
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; usin ...
- sql 补齐字段位数
select top 100 lmdte, right(replicate('0',6)+ltrim(lmtme),6) from smtpdsum where lmdte <> 0
- Android事件总线
Android中Activity.Service.Fragment之间的相互通信比较麻烦,主要有以下一些方法: (1)使用广播,发送者发出广播,接收者接收广播后进行处理: (2)使用Handler和M ...
- 计算(LnN!)的值
import java.util.*;import java.math.*;public class CaculatorLnN { public static void main(String[] a ...
- Atitit.ide技术原理与实践attilax总结
Atitit.ide技术原理与实践attilax总结 1.1. 语法着色1 1.2. 智能提示1 1.3. 类成员outline..func list1 1.4. 类型推导(type inferenc ...
- gRPC源码分析2-Server的建立
gRPC中,Server.Client共享的Class不是很多,所以我们可以单独的分别讲解Server和Client的源码. 通过第一篇,我们知道对于gRPC来说,建立Server是非常简单的,还记得 ...
- session 存入数据库 php
session 机制 1.php中session的生成机制 session是保存在服务器的,当我们在代码中调用session_start();时,PHP会同时往SESSION的存放目录(默认为/tm ...