From 30d4b36c27b1c9293f333a243d3075a687e4e2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=A0=91=E6=A3=AE?= Date: Wed, 17 Jul 2019 10:25:12 +0800 Subject: [PATCH] Create 130. Surrounded Regions.md --- solutions/130. Surrounded Regions.md | 56 ++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 solutions/130. Surrounded Regions.md diff --git a/solutions/130. Surrounded Regions.md b/solutions/130. Surrounded Regions.md new file mode 100644 index 0000000..2f5ac3c --- /dev/null +++ b/solutions/130. Surrounded Regions.md @@ -0,0 +1,56 @@ +# [130. Surrounded Regions](https://leetcode.com/problems/surrounded-regions/) +# 思路 +有一个二维的只包含O和X的矩形区域,题目要求将被X包住的O都变成X,边缘的O不算被包围。 +这题很容易想到的是遍历一遍矩形,若遇到了O,就从这个O出发进行DFS(或者BFS),看会不会遇到边界,如果遇不到则说明是被包围的,然后将这些O变成X。 + +但是上面的思路在矩形很大的时候亲测会超时,我们可以用反向思路考虑: +扫描矩阵的四条边,如果有O,则用DFS遍历,将所有连着的O都变成另一个字符比如N,这样剩下的O都是被包围的,最后将这些O变成X,把N变回O就行了。 +由于这个思路是只从矩形的四条边进行DFS,所以比最开始的思路复杂度要低很多(虽然理论复杂度都是O(m*n), m和n分别是矩形的高和宽)。 + + +# C++ +``` C++ +class Solution { +private: + vectordx{1, -1, 0, 0}; + vectordy{0, 0, 1, -1}; + int m, n; + void DFS(vector>& board, int i, int j){ + if(i < 0 || j < 0 || i > m-1 || j > n-1) return; // 超出矩形区域 + if(board[i][j] == 'X' || board[i][j] == 'N') return; + + // board[i][j] == 'O' + board[i][j] = 'N'; + int next_i, next_j; + for(int k = 0; k < 4; k++) { + next_i = i+dx[k]; + next_j = j+dy[k]; + // 提前判断一下会快不少 + if(next_i < 0 || next_j < 0 || next_i > m-1 || next_j > n-1) continue; + DFS(board, next_i, next_j); + } + } +public: + void solve(vector>& board) { + m = board.size(); + if(m == 0) return; + n = board[0].size(); + + for(int j = 0; j < n; j++){ + DFS(board, 0, j); + DFS(board, m-1, j); + } + + for(int i = 1; i < m-1; i++){ + DFS(board, i, 0); + DFS(board, i, n-1); + } + + for(int i = 0; i < m; i++) + for(int j = 0; j < n; j++){ + if(board[i][j] == 'N') board[i][j] = 'O'; + else if(board[i][j] == 'O') board[i][j] = 'X'; + } + } +}; +```