概述
417. 太平洋大西洋水流问题
题目来源:417. 太平洋大西洋水流问题
2022.04.27 每日一题
LeetCode 题解持续更新中GitHub仓库地址 CSDN博客地址
今天的题目是深度优先搜素/广度优先搜素的题目,我们需要判断一个网格能否流淌到海洋之中,我们首先想到的就是BFS/DFS进行搜索,但是如果每个格子都进行一次搜索,那么会导致某些格子被多次搜索,最终导致时间超时,那么我们可以更换一下想法,倒着搜索,从通过网格搜索是否可以到达海洋,转变成为从海洋开始搜索,判断可以经过哪些格子,通过的这些格子,就说明该格子可以流到海洋之中,我们只需要搜索两个海洋,并且将可以经过的格子进行标记,最后遍历两个数组,将相应的坐标放入结果数组之中,就可以得到最后的答案。
- 代码之中包含了DFS
以及BFS
两种,只需要将pacificAtlantic
函数中的 dfs 更换成为 bfs 即可两种相互转换。
- 别问为什么不单独写出来,问就是 懒 bushi
class Solution
{
// 创建两个变量,分别统计数组的大小
int m = 0, n = 0;
// 设置方向数组
vector<vector<int>> dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
// 设置两个 bool 数组,判断 能否从一个河流流淌到另一个河流
vector<vector<bool>> pacific, atlantic;
public:
vector<vector<int>> pacificAtlantic(vector<vector<int>> &heights)
{
m = heights.size();
n = heights[0].size();
pacific = vector<vector<bool>>(m, vector<bool>(n));
atlantic = vector<vector<bool>>(m, vector<bool>(n));
// 分别对靠近海洋周边的进行递归操作
for (int i = 0; i < m; i++)
{
dfs(i, 0, pacific, heights);
dfs(i, n - 1, atlantic, heights);
}
for (int i = 0; i < n; i++)
{
dfs(0, i, pacific, heights);
dfs(m - 1, i, atlantic, heights);
}
// 创建结果数组
vector<vector<int>> res;
// 遍历两个 布尔数组
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
// 只有当两者都可以相互流淌(两者均为真)的时候才满足条件
if (atlantic[i][j] && pacific[i][j])
{
res.push_back({i, j});
}
}
}
return res;
}
// 递归函数
void dfs(int r, int c, vector<vector<bool>> &check, vector<vector<int>> &heights)
{
// 如果当前的点已经满足了要求,就返回
if (check[r][c])
return;
// 将当前节点 置为 true 说明 该节点可以被 check 海洋访问
check[r][c] = true;
// 遍历四个方向
for (vector<int> &dir : dirs)
{
int xx = r + dir[0], yy = c + dir[1];
// 不满足要求就 continue
if (xx < 0 || yy < 0 || xx >= m || yy >= n || heights[xx][yy] < heights[r][c])
continue;
dfs(xx, yy, check, heights);
}
}
void bfs(int r, int c, vector<vector<bool>> &check, vector<vector<int>> &heights)
{
// 如果当前的点已经满足了要求,就返回
if (check[r][c])
return;
// 将当前节点 置为 true 说明 该节点可以被 check 海洋访问
check[r][c] = true;
// 创建 队列,进行迭代操作
queue<vector<int>> qu;
qu.push({r, c});
while (!qu.empty())
{
vector<int> temp = qu.front();
qu.pop();
for (vector<int> &dir : dirs)
{
int xx = temp[0] + dir[0], yy = temp[1] + dir[1];
// 不满足要求就 continue
if (xx < 0 || yy < 0 || xx >= m || yy >= n || check[xx][yy] || heights[xx][yy] < heights[temp[0]][temp[1]])
continue;
// 如果满足要求,就将对应的值 赋为 true,并且放入队列中进行 下一次的迭代
check[xx][yy] = true;
qu.push({xx, yy});
}
}
}
};
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
class Solution {
// 创建两个变量,分别统计数组的大小
int m = 0, n = 0;
// 设置方向数组
int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
// 设置两个 bool 数组,判断 能否从一个河流流淌到另一个河流
boolean[][] pacific, atlantic;
public List<List<Integer>> pacificAtlantic(int[][] heights) {
m = heights.length;
n = heights[0].length;
pacific = new boolean[m][n];
atlantic = new boolean[m][n];
// 分别对靠近海洋周边的进行递归操作
for (int i = 0; i < m; i++) {
dfs(i, 0, pacific, heights);
dfs(i, n - 1, atlantic, heights);
}
for (int i = 0; i < n; i++) {
dfs(0, i, pacific, heights);
dfs(m - 1, i, atlantic, heights);
}
// 创建结果数组
List<List<Integer>> res = new ArrayList<>();
// 遍历两个 布尔数组
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// 只有当两者都可以相互流淌(两者均为真)的时候才满足条件
if (atlantic[i][j] && pacific[i][j]) {
ArrayList<Integer> temp = new ArrayList<>();
temp.add(i);
temp.add(j);
res.add(temp);
}
}
}
return res;
}
// 递归函数
public void dfs(int r, int c, boolean[][] check, int[][] heights) {
// 如果当前的点已经满足了要求,就返回
if (check[r][c]) return;
// 将当前节点 置为 true 说明 该节点可以被 check 海洋访问
check[r][c] = true;
// 遍历四个方向
for (int[] dir : dirs) {
int xx = r + dir[0], yy = c + dir[1];
// 不满足要求就 continue
if (xx < 0 || yy < 0 || xx >= m || yy >= n || heights[xx][yy] < heights[r][c]) continue;
dfs(xx, yy, check, heights);
}
}
public void bfs(int r, int c, boolean[][] check, int[][] heights) {
// 如果当前的点已经满足了要求,就返回
if (check[r][c]) return;
// 将当前节点 置为 true 说明 该节点可以被 check 海洋访问
check[r][c] = true;
// 创建 队列,进行迭代操作
Queue<int[]> qu = new ArrayDeque<>();
qu.offer(new int[]{r, c});
while (!qu.isEmpty()) {
int[] temp = qu.poll();
for (int[] dir : dirs) {
int xx = temp[0] + dir[0], yy = temp[1] + dir[1];
// 不满足要求就 continue
if (xx < 0 || yy < 0 || xx >= m || yy >= n || check[xx][yy] || heights[xx][yy] < heights[temp[0]][temp[1]])
continue;
// 如果满足要求,就将对应的值 赋为 true,并且放入队列中进行 下一次的迭代
check[xx][yy] = true;
qu.offer(new int[]{xx, yy});
}
}
}
}
最后
以上就是鲤鱼蜜蜂为你收集整理的LeetCode 417. 太平洋大西洋水流问题题解417. 太平洋大西洋水流问题的全部内容,希望文章能够帮你解决LeetCode 417. 太平洋大西洋水流问题题解417. 太平洋大西洋水流问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复