之前都在poj玩,第一次刷LeetCode OJ的题目,求Surrounded Regions。原题http://oj.leetcode.com/problems/surrounded-regions/ 。
我一开始想用DP推导, board[i][j] = surrounded if{ board[i+_1][j+-1] ==' x' or board[i+_1][j+-1] got surrounded too},但是发现第二个条件很难判定。
然后再想起,任何一个O如果它没有被X包围,那么它一定和最外面的边界的某个O是连通的。反过来,也就是可以从最外面那层所有的O开始用广度搜索所有没有被包围的O。
PS下,一开始我直接用递归来广搜,但是当测试数据上到250*250矩阵后,直接递归导致的空间太大直接runtime error。然后改为用个Stack来搜索就ac了。
刷题这种东西还是讲状态,刚看到这题时候想着20分钟就能搞定,结果各种小bug。。。。。。。。。。。。
直接上代码,包括递归和非递归版本:
import java.lang.reflect.Array;
import java.io.*;
public class Solution {
public void solve(char[][] board)
{
if(board==null)
return;
int row=board.length;
if(row == 0)
return;
int col=board[0].length;
if(col == 0)
return;
boolean[][] vFlag = new boolean[row][col];
boolean[][] sFlag = new boolean[row][col];
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
sFlag[i][j] = true;
vFlag[i][j] = false;
}
}
// java.util.ArrayList<Integer> orIndex = new java.util.ArrayList<Integer>();
// java.util.ArrayList<Integer> ocIndex = new java.util.ArrayList<Integer>();
for(int i=0;i<row;i++)
{
if(board[i][0] == 'O')
{
if(vFlag[i][0] == false)
{
TraverNeighorhood_Breath( board, vFlag, sFlag, i, 0, row, col);
}
}
if(board[i][col-1] == 'o'|| board[i][col-1] == 'O')
{
if(vFlag[i][col-1] == false)
{
TraverNeighorhood_Breath( board, vFlag, sFlag, i, col-1, row, col);
}
}
}
for(int j=1;j<col-1;j++)
{
if(board[0][j] == 'O')
{
if(vFlag[0][j] == false)
{
TraverNeighorhood_Breath( board, vFlag, sFlag, 0, j, row, col);
}
}
if(board[row-1][j] == 'O')
{
if(vFlag[row-1][j] == false )
{
TraverNeighorhood_Breath( board, vFlag, sFlag, row-1, j, row, col);
}
}
}
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
if(sFlag[i][j] == true)
board[i][j] = 'X';
return;
}
public void TraverNeighorhood_Breath(char[][] board, boolean[][] vflag, boolean[][] sflag, int cr,int cc, int row, int col)
{
java.util.Stack<Integer> toVisNodes = new java.util.Stack<Integer>();
toVisNodes.add(cr*col+cc);
while(!toVisNodes.isEmpty())
{
int hashindex = toVisNodes.pop();
int trow = hashindex / col;
int tcol = hashindex % col;
if(vflag[trow][tcol] == true)
continue;
vflag[trow][tcol] = true;
sflag[trow][tcol] = false;
for(int i=-1;i<=1;i++)
for(int j=-1;j<=1;j++)
{
if( (i==0 || j==0) && (trow+i>=0 && trow+i<row && tcol+j>=0 && tcol+j<col) )
{
if( board[trow+i][tcol+j] == 'O' && vflag[trow+i][tcol+j] == false)
{
toVisNodes.add((trow+i)*col+tcol+j);
}
}
}
}
}
public void TraverNeighborhood(char[][] board, boolean[][] vflag, boolean[][] sflag, int cr,int cc, int row, int col)
{
//Going to visit board[i][j] which is already marked as unbounded.
for(int i=-1;i<=1;i++)
for(int j=-1;j<=1;j++)
{
if( (i==0 || j==0) && (cr+i>=0 && cr+i<row && cc+j>=0 && cc+j<col) )
{
if( board[cr+i][cc+j] == 'O' && vflag[cr+i][cc+j] == false)
{
vflag[cr+i][cc+j] = true;
sflag[cr+i][cc+j] = false;
TraverNeighborhood(board, vflag, sflag, cr+i,cc+j, row, col);
}
}
}
}
public static void main(String[] args) throws Exception
{
int row = 0,col = 0;
//java.util.Scanner scan = new java.util.Scanner(System.in);
BufferedReader bfread = new BufferedReader(new FileReader("output"));
String rc = bfread.readLine();
String[] strs = rc.split(" ");
row = Integer.parseInt(strs[0]);
col = Integer.parseInt(strs[1]);
char[][] board = new char[row][col];
int k = 0;
while(k<row)
{
String str = bfread.readLine();
for(int j=0;j<col;j++)
board[k][j]=str.charAt(j);
k++;
}
Solution sol = new Solution();
sol.solve(board);
IOFile ofile = new IOFile();
ofile.WriteBoard(board, "result");
System.out.println("Finished");
}
}