有意思的题目,同样的代码,小数据,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); } };