417. Pacific Atlantic Water Flow

    xiaoxiao2022-05-22  227

    417. Pacific Atlantic Water Flow

    方法0: wrong方法2: dfs 方法2: dfs 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).

    [ [1,2,3], [8,9,4], [7,6,5] ]

    方法0: wrong

    思路:

    这道题本来用dp做,但是错了。因为dp假设了pacific的水一定从左上流过来,atlantic一定从右下流过来,那么直接两次dp找两条单调非递减路线即可。但跑了一次啊发现了如下反例: [ [1,2,3], [8,9,4], [7,6,5] ] Output [[2,2],[2,0],[1,2],[1,1],[1,0],[0,2]] Expected [[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]

    事实证明为了到达[2, 1] , 海水是绕了弯的。所以还是只能用search。

    class Solution { public: vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) { if (matrix.empty() || matrix[0].empty()) return {}; int m = matrix.size(), n = matrix[0].size(); vector<vector<int>> dp1(m, vector<int> (n, 0)), dp2 = dp1; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j ++) { if (i == 0 || j == 0) dp1[i][j] = 1; else { if (matrix[i][j] >= matrix[i - 1][j]) { dp1[i][j] |= dp1[i - 1][j]; } if (matrix[i][j] >= matrix[i][j - 1]) { dp1[i][j] |= dp1[i][j - 1]; } } } } for (int i = m - 1; i >= 0; i--) { for (int j = n -1; j >= 0; j --) { if (i == m - 1 || j == n - 1) dp2[i][j] = 1; else { if (matrix[i][j] >= matrix[i + 1][j]) { dp2[i][j] |= dp2[i + 1][j]; } if (matrix[i][j] >= matrix[i][j + 1]) { dp2[i][j] |= dp2[i][j + 1]; } } } } vector<vector<int>> result; for (int i = m - 1; i >= 0; i--) { for (int j = n -1; j >= 0; j --) { if (dp1[i][j] && dp2[i][j]) result.push_back({i, j}); } } return result; } };

    方法2: dfs

    思路:

    从所有边界点开始同步发起bfs,将能渗透到的点标记。经过两次不同的bfs后,找到matrix上可以同时和两个大洋联通的点收集进结果即可。

    class Solution { public: vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) { if (matrix.empty() || matrix[0].empty()) return {}; int m = matrix.size(), n = matrix[0].size(); vector<vector<int>> dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; vector<vector<int>> pacific(m, vector<int>(n, 0)), atlantic = pacific; queue<vector<int>> q; // pacific first for (int i = 0; i < m; i++) { pacific[i][0] = 1; q.push({i, 0}); } for (int j = 1; j < n; j++) { pacific[0][j] = 1; q.push({0, j}); } bfs(matrix, pacific, q, dirs); // atlantic then for (int i = m - 1; i >= 0; i--) { atlantic[i][n - 1] = 1; q.push({i, n - 1}); } for (int j = n - 1; j >= 0; j--) { atlantic[m - 1][j] = 1; q.push({m - 1, j}); } bfs(matrix, atlantic, q, dirs); // collect result vector<vector<int>> result; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j ++) { if (pacific[i][j] && atlantic[i][j]) result.push_back({i, j}); } } return result; } void bfs(vector<vector<int>> & matrix, vector<vector<int>> & ocean, queue<vector<int>> & q, vector<vector<int>> & dirs){ int m = matrix.size(), n = matrix[0].size(); while (!q.empty()) { auto top = q.front(); q.pop(); for (auto dir: dirs) { int x = top[0] + dir[0], y = top[1] + dir[1]; if (x < 0 || x >= m || y < 0 || y >= n || ocean[x][y] || matrix[x][y] < matrix[top[0]][top[1]]) continue; ocean[x][y] = 1; q.push({x, y}); } } return; } };

    方法2: dfs


    最新回复(0)