有意思的题目,同样的代码,小数据,Java是600+ms,而C++就6ms。所以大数据Java超时。估计递归一多,Java的效率明显下降。
1. 思路是从外圈往里做标记,标记活下来的cell;
2. 因为螺旋打印很熟了,所以就螺旋的从外面往里面标记;
3. 但是发现了一个问题,错误的标记了第三行第四个为'X',因为旋转的顺序,下面那个当时还没标记。
OXXOX
XOOXO
XOXOX
OXOOO
XXOXO
OXXOX
XXXXO
XXXXX
OXOOO
XXOXO
4. 想到一个方法就是多转几圈,直到'#'的数字不变,但这个方法显然不够好,在3这个bad case的极端情况下,会循环很久;
5. 看了一下网上,就是从边上开始,找到标记为'#'的cell后,开始DFS/BFS,标记相邻的'O';
class Solution {
public:
void solve(vector<vector<char>> &board) {
int m = board.size();
if (m == 0) return;
int n = board[0].size();
if (n == 0) return;
for (int i = 0; i < n; i++)
{
update(board, 0, i);
}
for (int i = 1; i < m; i++)
{
update(board, i, n-1);
}
for (int i = n-2; i >= 0; i--)
{
update(board, m-1, i);
}
for (int i = m-2; i >=1; i--)
{
update(board, i, 0);
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (board[i][j]=='#') board[i][j] = 'O';
else if (board[i][j] == 'O') board[i][j] = 'X';
}
}
}
void update(vector<vector<char>> &board, int i, int j)
{
if (i >= board.size() || j >= board[0].size()) return;
if (board[i][j] == 'O')
{
board[i][j] = '#';
update(board, i-1, j);
update(board, i+1, j);
update(board, i, j-1);
update(board, i, j+1);
}
}
};
第二刷
class Solution {
public:
int N;
int M;
void solve(vector<vector<char>> &board)
{
if (board.empty() || board[0].empty()) return;
N = board.size();
M = board[0].size();
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
{
if (i == 0 || j == 0 || i == N-1 || j == M-1)
probe(board, i, j);
}
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
{
if (board[i][j] != '.')
board[i][j] = 'X';
else
board[i][j] = 'O';
}
}
void probe(vector<vector<char>> &board, int i, int j)
{
if (i < 0 || i >= N) return;
if (j < 0 || j >= M) return;
if (board[i][j] != 'O') return;
board[i][j] = '.';
probe(board, i-1, j);
probe(board, i+1, j);
probe(board, i, j-1);
probe(board, i, j+1);
}
};