题意

题目

思路

一开始想用双向广搜来做,找他们相碰的点,但是发现对其的理解还是不够完全,导致没写成功。不过,后来想清楚了,之前的错误可能在于从边界点进行BFS,其访问顺序应该是找到下一个比当前那个要大的点,但是我写反了。。可以先对左边的队列进行BFS,保存其visited,再接着对右边的队列进行BFS,当访问到之前已经访问过的结点时,则加入到结果中。

实现

//
// #include "../PreLoad.h" /*
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). */ class Solution {
public:
/**
* 从边界的点开始进行BFS,找出交叉的点,即为可以到达两边的点
* @param matrix
* @return
*/
vector<pair<int, int>> pacificAtlantic(vector<vector<int>>& matrix) {
vector<pair<int, int>> result;
if (matrix.size() == 0) {
return result;
} // 双向BFS,找重合点
queue<pair<int, int>> pa_queue; //太平洋
queue<pair<int, int>> at_queue; //大西洋 size_t row = matrix.size();
size_t col = matrix[0].size(); vector<vector<int>> layouts = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
auto state_bfs = [&](queue<pair<int, int>>& queue, vector<vector<int>>& visit) {
while (!queue.empty()) {
pair<int, int> content = queue.front();
queue.pop(); int height = content.first;
int x = content.second / col;
int y = content.second % col; for (auto temp : layouts) {
int newx = temp[0] + x;
int newy = temp[1] + y; // 因为是从边界结点开始,题目又要求某个点从高往低到两个海洋,所以边界点访问顺序则为递增
if (newx < 0 || newx >= row || newy < 0 || newy >= col || visit[newx][newy] || matrix[newx][newy] < height) {
continue;
} queue.push({matrix[newx][newy], newx * col + newy});
visit[newx][newy] = 1;
}
}
}; vector<vector<int>> visited1(row, vector<int>(col, 0));
vector<vector<int>> visited2(row, vector<int>(col, 0)); // 第一行和第一列
for (int i = 0; i < col; i++) {
pa_queue.push({matrix[0][i], i});
visited1[0][i] = 1; at_queue.push({matrix[row-1][i], (row-1) * col + i});
visited2[row-1][i] = 1;
}
for (int i = 0; i < row; i++) {
pa_queue.push({matrix[i][0], i * col});
visited1[i][0] = 1; at_queue.push({matrix[i][col-1], i * col + col-1});
visited2[i][col-1] = 1;
} state_bfs(pa_queue, visited1);
state_bfs(at_queue, visited2); // 交叉点则为可以到达两边的点
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (visited1[i][j] && visited2[i][j]) {
result.push_back({i, j});
}
}
} return result;
} vector<pair<int, int>> pacificAtlantic2(vector<vector<int>>& matrix) {
vector<pair<int, int>> result;
if (matrix.size() == 0) {
return result;
} // 双向BFS,找重合点
queue<pair<int, int>> pa_queue; //太平洋
queue<pair<int, int>> at_queue; //大西洋 size_t row = matrix.size();
size_t col = matrix[0].size(); vector<vector<int>> layouts = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
auto state_bfs = [&](queue<pair<int, int>>& queue, vector<vector<int>>& visit, bool flag) {
while (!queue.empty()) {
pair<int, int> content = queue.front();
queue.pop(); int height = content.first;
int x = content.second / col;
int y = content.second % col; for (auto temp : layouts) {
int newx = temp[0] + x;
int newy = temp[1] + y; // 因为是从边界结点开始,题目又要求某个点从高往低到两个海洋,所以边界点访问顺序则为递增
if (newx < 0 || newx >= row || newy < 0 || newy >= col || matrix[newx][newy] < height) {
continue;
} if (flag) {
if (visit[newx][newy] != 1) {
// 已经被另外一个访问过
if (visit[newx][newy] == 2) {
result.push_back({newx, newy});
continue;
} queue.push({matrix[newx][newy], newx * col + newy});
visit[newx][newy] = 1;
}
}
else {
if (visit[newx][newy] != 2) {
// 已经被另外一个访问过
if (visit[newx][newy] == 1) {
result.push_back({newx, newy});
continue;
} queue.push({matrix[newx][newy], newx * col + newy});
visit[newx][newy] = 2;
}
}
}
}
}; vector<vector<int>> visited1(row, vector<int>(col, 0));
vector<vector<int>> visited2(row, vector<int>(col, 0)); // 第一行和第一列
for (int i = 0; i < col; i++) {
pa_queue.push({matrix[0][i], i});
visited1[0][i] = 1; at_queue.push({matrix[row-1][i], (row-1) * col + i});
visited2[row-1][i] = 2;
}
for (int i = 0; i < row; i++) {
pa_queue.push({matrix[i][0], i * col});
visited1[i][0] = 1; at_queue.push({matrix[i][col-1], i * col + col-1});
visited2[i][col-1] = 2;
} while (!pa_queue.empty() || !at_queue.empty()) {
if (!pa_queue.empty()) {
state_bfs(pa_queue, visited1, true);
} if (!at_queue.empty()) {
state_bfs(at_queue, visited2, false);
}
} // 交叉点则为可以到达两边的点
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (visited1[i][j] && visited2[i][j]) {
result.push_back({i, j});
}
}
} return result;
} void test() {
vector<vector<int>> matrix = {
{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}
}; vector<pair<int, int>> result = this->pacificAtlantic2(matrix);
for (int i = 0; i < result.size(); i++) {
pair<int, int> content = result[i];
cout << "(" << content.first << ", " << content.second << ")" << endl;
}
}
};

[LeetCode] Pacific Atlantic Water Flow 题解的更多相关文章

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

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

  3. LeetCode 417. Pacific Atlantic Water Flow

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

  4. [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 ...

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

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

  6. [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 ...

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

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

  8. 417. Pacific Atlantic Water Flow

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

  9. [LeetCode] Trapping Rain Water II 题解

    题意 题目 思路 我一开始想的时候只考虑到一个结点周围的边界的情况,并没有考虑到边界的高度其实影响到所有的结点盛水的高度. 我们可以发现,中间是否能够盛水取决于边界是否足够高于里面的高度,所以这必然是 ...

随机推荐

  1. ClientDataset 三层 var and out arguments must match parameter

    ​​​将Delphi升级到10.1.2后,从客户端传ClientDataset的Delta数据到服务端程序时,出现var and out arguments must match parameter错 ...

  2. 修改类不用重启Tomcat加载整个项目

    可以修改类不用重启Tomcat加载整个项目(手工启动) 配置reloadable=true(自动重载) 使用Debug模式,前提是仅限于局部修改.(修改类不用重启--热加载) Tomcat轻小,而We ...

  3. Visual Studio 2017 for Mac

    Visual Studio 2017 for Mac Last Update: 2017/6/16 我们非常荣幸地宣布 Visual Studio 2017 for Mac 现已推出. Visual ...

  4. NLP里面好的学习资料

    别人推荐的网址: http://ruder.io/deep-learning-nlp-best-practices/index.html#wordembeddings

  5. No.13 selenium for python 单选框和复选框

    单选框 radio 点击图标,可以获取HTML中定位. 使用普通的ID定位就可以了 定位到指定元素,然后使用clicd选中即可 复选框 checkbox 勾选单个框,跟单选框一样,定位后点击就可以了 ...

  6. 漂亮的SVG时钟

    漂亮的SVG时钟 效果图: 代码如下,复制即可使用: <!DOCTYPE html> <html lang="en"> <head> <m ...

  7. springMVC源码分析--HttpMessageConverter写write操作(三)

    上一篇博客springMVC源码分析--HttpMessageConverter参数read操作中我们已经简单介绍了参数值转换的read操作,接下来我们介绍一下返回值的处理操作.同样返回值的操作操作也 ...

  8. Python学习笔记:出生日期转化为年龄

    在数据挖掘项目中,有时候个体的出生日期包含信息量过大,不适合作为一个有效数据进入模型算法训练,因此有必要把出生日期转化为年龄age,age是一个很好的特征工程指示变量. import pandas a ...

  9. 我常用的 Python 调试工具 - 博客 - 伯乐在线

    .ckrating_highly_rated {background-color:#FFFFCC !important;} .ckrating_poorly_rated {opacity:0.6;fi ...

  10. hdu 5446(2015长春网络赛J题 Lucas定理+中国剩余定理)

    题意:M=p1*p2*...pk:求C(n,m)%M,pi小于10^5,n,m,M都是小于10^18. pi为质数 M不一定是质数 所以只能用Lucas定理求k次 C(n,m)%Pi最后会得到一个同余 ...