題目描述:
有一個 m × n 的矩形島嶼,與 太平洋 和 大西洋 相鄰。 “太平洋” 處于大陸的左邊界和上邊界,而 “大西洋” 處于大陸的右邊界和下邊界。
這個島被分割成一個由若干方形單元格組成的網格。給定一個 m x n 的整數矩陣 heights , heights[r][c] 表示坐標 (r, c) 上單元格 高于海平面的高度 。
島上雨水較多,如果相鄰單元格的高度 小于或等于 當前單元格的高度,雨水可以直接向北、南、東、西流向相鄰單元格。水可以從海洋附近的任何單元格流入海洋。
返回網格坐標 result 的 2D 列表 ,其中 result[i] = [ri, ci] 表示雨水從單元格 (ri, ci) 流動 既可流向太平洋也可流向大西洋 。
示例1:
輸入: heights = [[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]]
輸出: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]
示例 2:
輸入: heights = [[2,1],[1,2]]
輸出: [[0,0],[0,1],[1,0],[1,1]]
力扣題目鏈接:
https://leetcode.cn/problems/pacific-atlantic-water-flow/
題解思路:深度優先搜索,從邊界處進行搜索,尋找符合條件的單元格,從太平洋邊上的節點 逆流而上,將遍歷過的節點都標記上,從大西洋的邊上節點 逆流而長,將遍歷過的節點也標記上,最后放入都符合條件的數組即可
下面給出ACM模式代碼,包含了核心代碼,可以自行驗證,主要是熟悉下ACM模式
#include <iostream>
#include <vector>
using namespace std;// 核心代碼部分
class Solution {
private:int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1}; // 保存四個方向// 深度優先搜索void dfs(vector<vector<int>>& heights, vector<vector<bool>>& visited, int x, int y) {if (visited[x][y]) return;visited[x][y] = true;for (int i = 0; i < 4; i++) { // 向四個方向遍歷long int nextx = x + dir[i][0];long int nexty = y + dir[i][1];// 超過邊界if (nextx < 0 || nextx >= heights.size() || nexty < 0 || nexty >= heights[0].size()) continue;// 高度不合適,注意這里是從低向高判斷if (heights[x][y] > heights[nextx][nexty]) continue;dfs (heights, visited, nextx, nexty);}return;}public:vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {vector<vector<int>> result;int n = heights.size();int m = heights[0].size();// 記錄從太平洋邊出發,可以遍歷的節點vector<vector<bool>> pacific = vector<vector<bool>>(n, vector<bool>(m, false));// 記錄從大西洋出發,可以遍歷的節點vector<vector<bool>> atlantic = vector<vector<bool>>(n, vector<bool>(m, false));// 從最上最下行的節點出發,向高處遍歷for (int i = 0; i < n; i++) {dfs (heights, pacific, i, 0); // 遍歷最左列,接觸太平洋 dfs (heights, atlantic, i, m - 1); // 遍歷最右列,接觸大西 }// 從最左最右列的節點出發,向高處遍歷for (int j = 0; j < m; j++) {dfs (heights, pacific, 0, j); // 遍歷最上行,接觸太平洋dfs (heights, atlantic, n - 1, j); // 遍歷最下行,接觸大西洋}for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 如果這個節點,從太平洋和大西洋出發都遍歷過,就是結果if (pacific[i][j] && atlantic[i][j]) result.push_back({i, j});}}return result;}
};int main() {int m, n; // 定義行和列int num; // 輸入的不同數字Solution s;vector<vector<int>> res; // 定義一個二維數組// 輸入數據while (cin >> m >> n) {if (m == 0 && n == 0) break;res.resize(m, vector<int>(n));for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {cin >> num;res[i][j] = num;}}vector<vector<int>> result = s.pacificAtlantic(res);cout << "輸出結果為:" << "["; for (int i = 0; i < result.size(); i++) { cout << "[" << result[i][0] << "," << result[i][1] << "]"; }cout << "]" << endl;}return 0;
}