题目:
多源BFS就是从多个起点(sources)同时开始 BFS。它的关键思想是:把多个“源点”都放入队列作为初始层(第0层),然后一次 BFS 把它们同时向外扩展。这相当于所有源点一起“扩散波动”,每个节点第一次被访问到的层数就是到最近源点的最短距离。
这个题如果用普通BFS要对每个顶点都得做一次BFS,因此用多源BFS会更好,即如果一个单元格能流到某海洋(太平洋或大西洋)那么高于它的邻居必定也能流到该单元格能到达的海洋。
初始化时让岛岸边的所有点入队,即边界上的所有单元格,每次出队一个单元格,如果该单元格的邻居中高度高于该单元格的,那么该单元格能到达的海洋,这个邻居也能到达。
关键问题是如何处理重复的问题,每个单元格有两个状态,只有固定了这两个状态,确定这两个状态不会改变了,才是处理完成的。因此如果在四个邻居的处理中某个邻居的状态没有发生改变,就不让它入队,将发生状态改变的邻居入队。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include <queue> #include <utility> #include <vector>
using std::pair; using std::queue; using std::vector;
class Solution { public: vector<vector<int>> pacificAtlantic(vector<vector<int>> &heights) { int m = heights.size(), n = heights[0].size(); int i, j, k; int neighbor_i, neighbor_j; int arr[] = {-1, 0, 1, 0, -1}; queue<pair<int, int>> que; vector<vector<pair<int, int>>> vec(m, vector<pair<int, int>>(n, {-1, -1})); bool updated = false; vector<vector<int>> result;
for (int j = 0; j < n; j++) { vec[0][j].first = 1; vec[m - 1][j].second = 1; que.push({0, j}); que.push({m - 1, j}); } for (int i = 0; i < m; i++) { vec[i][0].first = 1; vec[i][n - 1].second = 1; que.push({i, 0}); que.push({i, n - 1}); }
while (!que.empty()) { i = que.front().first; j = que.front().second;
que.pop(); for (k = 0; k <= 3; k++) { neighbor_i = i + arr[k]; neighbor_j = j + arr[k + 1]; updated = false; if ((neighbor_i >= 0 && neighbor_i < m && neighbor_j >= 0 && neighbor_j < n) && heights[neighbor_i][neighbor_j] >= heights[i][j]) {
if (vec[i][j].first == 1 && vec[neighbor_i][neighbor_j].first != 1) { vec[neighbor_i][neighbor_j].first = 1; updated = true; } if (vec[i][j].second == 1 && vec[neighbor_i][neighbor_j].second != 1) { vec[neighbor_i][neighbor_j].second = 1; updated = true; }
if (updated) { que.push({neighbor_i, neighbor_j}); } } } }
for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { if (vec[i][j].first == 1 && vec[i][j].second == 1) { result.push_back({i, j}); } } }
return result; } };
|