|
| 1 | +// Time: O(m * n) |
| 2 | +// Space: O(m + n) |
| 3 | + |
| 4 | +class Solution { |
| 5 | +public: |
| 6 | + template <typename T> |
| 7 | + struct PairHash { |
| 8 | + size_t operator()(const pair<T, T>& p) const { |
| 9 | + size_t seed = 0; |
| 10 | + seed ^= std::hash<T>{}(p.first) + 0x9e3779b9 + (seed<<6) + (seed>>2); |
| 11 | + seed ^= std::hash<T>{}(p.second) + 0x9e3779b9 + (seed<<6) + (seed>>2); |
| 12 | + return seed; |
| 13 | + } |
| 14 | + }; |
| 15 | + |
| 16 | + vector<vector<int>> colorBorder(vector<vector<int>>& grid, int r0, int c0, int color) { |
| 17 | + static const vector<pair<int, int>> directions{{0, -1}, {0, 1}, |
| 18 | + {-1, 0}, {1, 0}}; |
| 19 | + vector<pair<int, int>> borders; |
| 20 | + unordered_set<pair<int, int>, PairHash<int>> lookup{make_pair(r0, c0)}; |
| 21 | + queue<pair<int, int>> q({make_pair(r0, c0)}); |
| 22 | + while (!q.empty()) { |
| 23 | + int r, c; |
| 24 | + tie(r, c) = q.front(); q.pop(); |
| 25 | + bool is_border = false; |
| 26 | + |
| 27 | + for (const auto& dir : directions) { |
| 28 | + const auto nr = r + dir.first, nc = c + dir.second; |
| 29 | + if (!((0 <= nr && nr < grid.size()) && |
| 30 | + (0 <= nc && nc < grid[0].size()) && |
| 31 | + grid[nr][nc] == grid[r][c])) { |
| 32 | + is_border = true; |
| 33 | + continue; |
| 34 | + } |
| 35 | + if (lookup.count(make_pair(nr, nc))) { |
| 36 | + continue; |
| 37 | + } |
| 38 | + lookup.emplace(nr, nc); |
| 39 | + q.emplace(nr, nc); |
| 40 | + } |
| 41 | + |
| 42 | + if (is_border) { |
| 43 | + borders.emplace_back(r, c); |
| 44 | + } |
| 45 | + } |
| 46 | + |
| 47 | + for (const auto& border : borders) { |
| 48 | + grid[border.first][border.second] = color; |
| 49 | + } |
| 50 | + return grid; |
| 51 | + } |
| 52 | +}; |
0 commit comments