LeetCode - Surrounded Regions

  之前都在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");
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值