417. Pacific Atlantic Water Flow
来源:互联网 发布:程序员培训机构 编辑:程序博客网 时间:2024/05/01 23:03
题目:
417. Pacific Atlantic Water Flow
- Total Accepted: 11498
- Total Submissions: 34789
- Difficulty: Medium
- Contributor: LeetCode
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 * * * * * * AtlanticReturn:[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix).
解题思路:
这题与我之前做过的Number of Islands类似,都是将DFS运用在矩阵问题上。用DFS遍历矩阵,用两个boolean数组p和a来记录每个点是否可以到达太平洋和大西洋,然后递归地对它上下左右连通的点进行访问,直到走到边界处,将p[i][j]或a[i][j]的值赋1。若该点的下一个点能够与海洋连通,则该点也能与海洋相连。为了提高算法效率,可以在每次递归调用DFS之前先判断下一个点是否能与海洋连通,若可以则无需再调用DFS。
对一个点做完DFS之后如果p[i][j]和a[i][j]都为1则将其加入输出vector
代码:
class Solution {public:int m, n;vector<pair<int, int>> res;bool p[150][150] = {0};bool a[150][150] = {0}; vector<pair<int, int>> pacificAtlantic(vector<vector<int>>& matrix) { if(!res.empty()) res.clear(); if(matrix.empty()) return res; m = matrix.size(); n = matrix[0].size(); for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ DFS(matrix, i, j); if(p[i][j] && a[i][j]){ pair<int, int> temp; temp.first = i; temp.second = j; res.push_back(temp); } } } return res; } void DFS(vector<vector<int>>& matrix, int i, int j){ if(i == 0 || j == 0) p[i][j] = 1; if(i == m - 1 || j == n - 1) a[i][j] = 1; //up if(i - 1 >= 0 && matrix[i - 1][j] <= matrix[i][j]){ if(p[i - 1][j]) p[i][j] = 1; if(a[i - 1][j]) a[i][j] = 1; if(!p[i - 1][j] && !a[i - 1][j]){ DFS(matrix, i - 1, j); if(p[i - 1][j]) p[i][j] = 1; if(a[i - 1][j]) a[i][j] = 1; } } //down if(i + 1 < m && matrix[i + 1][j] <= matrix[i][j]){ if(p[i + 1][j]) p[i][j] = 1; if(a[i + 1][j]) a[i][j] = 1; if(!p[i + 1][j] && !a[i + 1][j]){ DFS(matrix, i + 1, j); if(p[i + 1][j]) p[i][j] = 1; if(a[i + 1][j]) a[i][j] = 1; } } //left if(j - 1 >= 0 && matrix[i][j - 1] <= matrix[i][j]){ if(p[i][j - 1]) p[i][j] = 1; if(a[i][j - 1]) a[i][j] = 1; if(!p[i][j - 1] && !a[i][j - 1]){ DFS(matrix, i, j - 1); if(p[i][j - 1]) p[i][j] = 1; if(a[i][j - 1]) a[i][j] = 1; } } //right if(j + 1 < m && matrix[i][j + 1] <= matrix[i][j]){ if(p[i][j + 1]) p[i][j] = 1; if(a[i][j + 1]) a[i][j] = 1; if(!p[i][j + 1] && !a[i][j + 1]){ DFS(matrix, i, j - 1); if(p[i][j + 1]) p[i][j] = 1; if(a[i][j + 1]) a[i][j] = 1; } } }};
其他答案:
做完之后看了一下solution里的解法发现可以倒过来想,把矩阵的边界点当做起点进行DFS,这样DFS树上的每一点都是可以到达海洋的,就不会存在我的做法中重复走的问题了。参考代码如下:
public class Solution { public List<int[]> pacificAtlantic(int[][] matrix) { List<int[]> res = new LinkedList<>(); if(matrix == null || matrix.length == 0 || matrix[0].length == 0){ return res; } int n = matrix.length, m = matrix[0].length; boolean[][]pacific = new boolean[n][m]; boolean[][]atlantic = new boolean[n][m]; for(int i=0; i<n; i++){ dfs(matrix, pacific, Integer.MIN_VALUE, i, 0); dfs(matrix, atlantic, Integer.MIN_VALUE, i, m-1); } for(int i=0; i<m; i++){ dfs(matrix, pacific, Integer.MIN_VALUE, 0, i); dfs(matrix, atlantic, Integer.MIN_VALUE, n-1, i); } for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (pacific[i][j] && atlantic[i][j]) res.add(new int[] {i, j}); return res; } int[][]dir = new int[][]{{0,1},{0,-1},{1,0},{-1,0}}; public void dfs(int[][]matrix, boolean[][]visited, int height, int x, int y){ int n = matrix.length, m = matrix[0].length; if(x<0 || x>=n || y<0 || y>=m || visited[x][y] || matrix[x][y] < height) return; visited[x][y] = true; for(int[]d:dir){ dfs(matrix, visited, matrix[x][y], x+d[0], y+d[1]); } }}
可以学习别人用二位数组来表示方向的方法,这样可以使得代码更加简洁。
除了DFS还可以使用BFS,使用两个队列即可,做法与DFS大同小异。
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- 417. Pacific Atlantic Water Flow
- Pacific Atlantic Water Flow
- LeetCode—417. Pacific Atlantic Water Flow
- Leetcode-417. Pacific Atlantic Water Flow
- LeetCode 417. Pacific Atlantic Water Flow 题解
- 417. Pacific Atlantic Water Flow dfs
- 【Leetcode】417. Pacific Atlantic Water Flow
- leetcode 417. Pacific Atlantic Water Flow
- bios中 启动首选项 找不到固态硬盘
- python3 静态方法和类方法的区别
- Android中你不得不知的几个问题及解决方法
- 百度代码规范 -- PHP
- Discuz代码研究-编码规范
- 417. Pacific Atlantic Water Flow
- 家庭理财规划之一
- 子网划分知识点及题目
- javaScript笔记
- R语言学习之基础知识二
- 解决spring boot中swagger-ui.html访问404以及配置全局header
- leetcode 513 Find Bottom Left Tree Value C++
- 329. Longest Increasing Path in a Matrix(第七周)
- 引用