LeetCode 130. Surrounded Regions

本文介绍了一种解决LeetCode中围绕区域问题的方法,通过BFS或DFS算法找到与边界相连的所有'O'并标记,最后将未与边界相连的'O'替换为'X'。

原题链接在这里:https://leetcode.com/problems/surrounded-regions/description/

题目:

Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

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

Explanation:

Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.

题解:

第一行和最后一行,第一列和最后一列,若是有'O'才能保留,并且和它们相连的'O'才能同时保留。

所以从这四条边上的'O' 点开始做BFS 或者 DFS, 把所有相连的点都变成 '#'.

最后扫描一遍board, 先判定这点若还是 'O', 说明这个'O'没有与边界相连,即是被包围的'O', 改为'X'.

后判定这点若是'#', 说明这个'O'与边界相连,应该保存,改回'O'.

Note: 无论是BFS还是DFS都应该有个used来check 之前是否visit 过这个cell. 否则就会无限循环. 这里可以先在board上更改, 再进queue, 如果出queue再更改就会有重复进queue的情况.

Time Complexity: O(m*n).

Space: O(m*n).

AC Java:

 1 class Solution {
 2     private int [][] dirs = {{-1, 0},{1, 0},{0, -1},{0, 1}};
 3     
 4     public void solve(char[][] board) {
 5         if(board == null || board.length == 0 || board[0].length == 0){
 6             return;
 7         }
 8         
 9         int m = board.length;
10         int n = board[0].length;
11         for(int j = 0; j<n; j++){
12             if(board[0][j] == 'O'){
13                 // bfs(board, 0, j);
14                 dfs(board, 0, j);
15             }
16             
17             if(board[m-1][j] == 'O'){
18                 // bfs(board, m-1, j);
19                 dfs(board, m-1, j);
20             }
21         }
22         
23         for(int i = 0; i<m; i++){
24             if(board[i][0] == 'O'){
25                 // bfs(board, i, 0);
26                 dfs(board, i, 0);
27             }
28             
29             if(board[i][n-1] == 'O'){
30                 // bfs(board, i, n-1);
31                 dfs(board, i, n-1);
32             }
33         }
34         
35         for(int i = 0; i<m; i++){
36             for(int j = 0; j<n; j++){
37                 if(board[i][j] == 'O'){
38                     board[i][j] = 'X';
39                 }
40                 
41                 if(board[i][j] == '#'){
42                     board[i][j] = 'O';
43                 }
44             }
45         }
46     }
47     
48     private void dfs(char [][] board, int i ,int j){
49         if(i<0 || i>=board.length || j<0 || j>=board[0].length || board[i][j]!='O'){
50             return;
51         }
52         
53         board[i][j] = '#';
54         for(int [] dir : dirs){
55             dfs(board, i+dir[0], j+dir[1]);
56         }
57     }
58     
59     private void bfs(char [][] board, int i, int j){
60         int m = board.length;
61         int n = board[0].length;
62         
63         if(i<0 || i>=m || j<0 || j>=n){
64             return;
65         }
66     
67         LinkedList<Integer> que = new LinkedList<Integer>();
68         board[i][j] = '#';
69         que.add(getIndex(i, j, n));
70         
71         while(!que.isEmpty()){
72             int cur = que.poll();
73             int p = cur/n;
74             int q = cur%n;
75             
76             for(int [] dir : dirs){
77                 int xp = p + dir[0];
78                 int xq = q + dir[1];
79                 if(xp>=0 && xp<m && xq>=0 && xq<n && board[xp][xq] == 'O'){
80                     board[xp][xq] = '#';
81                     que.add(getIndex(xp, xq, n));
82                 }
83             }
84         }
85     }
86     
87     private int getIndex(int i, int j, int n){
88         return i*n+j;
89     }
90 }

 

转载于:https://www.cnblogs.com/Dylan-Java-NYC/p/4886925.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值