原題地址
https://leetcode.com/problems/surrounded-regions/
題目描述
Given a 2D board containing ‘X’ and ‘O’, capture all regions surrounded by ‘X’.
給出一個2D圖板,又字符’X’和’O’組成,捕捉被’X’包圍的區域。
A region is captured by flipping all ‘O’s into ‘X’s in that surrounded region.
將被’X’包圍的區域全部置爲’X’就是對這個區域進行“逮捕”。
For example,
例如:
X X X X
X O O X
X X O X
X O X X
After running your function, the board should be:
在逮捕之後,應該變成:
X X X X
X X X X
X X X X
X O X X
解題思路
廣度優先遍歷
- 最外層如果有O的話一定不會被包圍
- 如果一個O不會被包圍,那他的周圍(上下左右)的O也不會被包圍。
算法描述
- 拷貝原數據爲copy
- 將周圍一圈中的’O’入棧queue
- 原始數據的中間部分(除去周圍一圈)全部置爲’X’
- 當queue不爲空時,取出棧頂元素,並判定其上下左右的4個位置的原始數據(copy中存儲着原始數據)是否爲’O’,如果是則將其置爲’O’
注意:爲了防止重複訪問,需要右標誌位visited[x][y]來記錄一個點是否已訪問過。
空間複雜度O(n),時間複雜度O(n)。
代碼 cpp
class MyPoint {
public:
int x;
int y;
MyPoint(int x, int y) : x(x), y(y) {}
};
class Solution {
public:
void solve(vector<vector<char> > &board) {
int rowSize = board.size(), colSize = rowSize > 0 ? board[0].size() : 0;
if (rowSize <= 2 || colSize <= 2) return;
vector<vector<char> > copy = vector<vector<char> >(board.begin(), board.end());
vector<vector<bool> > visited = vector<vector<bool> >(rowSize, vector<bool>(colSize, false));
--rowSize;
--colSize;
queue<MyPoint *> q;
if (copy[0][0] == 'O') {
q.push(new MyPoint(0, 0));
visited[0][0] = true;
}
if (copy[0][colSize] == 'O') {
q.push(new MyPoint(0, colSize));
visited[0][colSize] = true;
}
if (copy[rowSize][0] == 'O') {
q.push(new MyPoint(rowSize, 0));
visited[rowSize][0] = true;
}
if (copy[rowSize][colSize] == 'O') {
q.push(new MyPoint(rowSize, colSize));
visited[rowSize][colSize] = true;
}
for (int i = 1; i < colSize; ++i) {
if (copy[0][i] == 'O')
q.push(new MyPoint(0, i));
if (copy[rowSize][i] == 'O')
q.push(new MyPoint(rowSize, i));
}
for (int i = 1; i < rowSize; ++i) {
if (copy[i][0] == 'O')
q.push(new MyPoint(i, 0));
if (copy[i][colSize] == 'O')
q.push(new MyPoint(i, colSize));
}
for (int i = 1; i < rowSize; ++i)
for (int j = 1; j < colSize; ++j)
board[i][j] = 'X';
MyPoint *tmp;
int dalx[] = {-1, 0, 1, 0}, daly[] = {0, 1, 0, -1};
int x, y;
while (!q.empty()) {
tmp = q.front();
q.pop();
for (int i = 0; i < 4; ++i) {
x = tmp->x + dalx[i];
y = tmp->y + daly[i];
if (x < 1 || y < 1 || x > rowSize || y > colSize)
continue;
if (copy[x][y] == 'O' && !visited[x][y]) {
board[x][y] = 'O';
visited[x][y] = true;
q.push(new MyPoint(x, y));
}
}
delete(tmp);
}
}
};
完整代碼https://github.com/Orange1991/leetcode/blob/master/130/cpp/main.cpp
運行情況
Status : Accept
Time : 20ms
2015/7/22