
深度优先遍历
解题思路:时间复杂度O(
m
∗
n
m*n
m∗n)所有元素都遍历一遍,空间复杂度O(
m
∗
n
m*n
m∗n) |
---|
- 我们发现,处于四周的O是无法被包围的,因此与四周O相连的O区域也是无法被包围的
- 因此这道题就是找到包含四周的O的区域,这些区域无法被包围。
- 而其它地方都可以被修改为X。因此我们将包含四周的O的区域标识出来,最后通过遍历整个数组,只要不是这片被标识的区域,就赋值为X
代码:0ms的算法和1ms的代码是完全一样的,但是可读性较差,因为它将遍历四周的代码不是用一个for循环实现,而是用多个for循环。虽然快一点,但是太冗余了。 |
---|
- 1ms代码,可读性较高

class Solution {
char[][] board;
boolean[][] visited;
int n,m;
int [][] directions = new int[][]{{-1,0},{0,-1},{1,0},{0,1}};
public void solve(char[][] board) {
this.board = board;
this.n = board.length;this.m = board[0].length;
visited = new boolean[n][m];
for(int i = 0;i<n;i++){
int num = i == 0 || i == n-1 ? 1:m-1;
for(int j = 0;j<m;j+=num){
if(board[i][j] == 'O' && !visited[i][j]) dfs(i,j);
}
}
for(int i = 0;i<n;i++){
for(int j = 0;j<m;j++){
if(!visited[i][j])board[i][j] = 'X';
}
}
}
public void dfs(int i,int j){
visited[i][j] = true;
for(int[] direction:directions){
int nextI = i+direction[0];
int nextJ = j+direction[1];
if(nextI<0 || nextI>=n || nextJ<0 || nextJ>=m || visited[nextI][nextJ] || board[nextI][nextJ] == 'X') continue;
dfs(nextI,nextJ);
}
}
}
- 0ms代码

class Solution {
private static final int[] dx = {0,0,-1,1};
private static final int[] dy = {-1,1,0,0};
public void solve(char[][] board) {
int n = board.length,m = board[0].length;
for(int i = 0;i < n;i ++){
if(board[i][0] == 'O') dfs(i,0,board);
if(board[i][m - 1] == 'O') dfs(i,m - 1,board);
}
for(int i = 0;i < m;i ++){
if(board[0][i] == 'O') dfs(0,i,board);
if(board[n - 1][i] == 'O') dfs(n - 1,i,board);
}
replace('O','X',board);
replace('1','O',board);
}
private void dfs(int x,int y,char[][] board) {
board[x][y] = '1';
for(int i = 0;i < 4;i ++) {
int tx = x + dx[i],ty = y + dy[i];
if(tx >= 0 && tx < board.length && ty >= 0 && ty < board[0].length && board[tx][ty] == 'O')
dfs(tx,ty,board);
}
}
private void replace(char oldChr,char newChr,char[][] board) {
for(int i = 0;i < board.length;i ++)
for(int j = 0;j < board[0].length;j ++)
if(board[i][j] == oldChr) board[i][j] = newChr;
}
}