zoukankan      html  css  js  c++  java
  • Surrounded Regions

    问题描述

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

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

    For 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

    解决思路

    反向思路,先识别出那些不可能被填充的点,用一种特殊记号标记出;

    然后扫描矩阵,将'O'进行'X'填充;

    最后将那些特殊标记的点复原即可。

    程序

    1. DFS (栈溢出)

    public class Solution {
        public void solve(char[][] board) {
    		if (board == null || board.length <= 2 || board[0].length <= 2) {
    			return;
    		}
    
    		int rows = board.length, cols = board[0].length;
    		for (int j = 0; j < cols; j++) {
    			dfs(board, 0, j);
    			dfs(board, rows - 1, j);
    		}
    		for (int i = 0; i < rows; i++) {
    			dfs(board, i, 0);
    			dfs(board, i, cols - 1);
    		}
    		for (int i = 0; i < rows; i++) {
    			for (int j = 0; j < cols; j++) {
    				if (board[i][j] == 'y') {
    					board[i][j] = 'O';
    				}else if (board[i][j] == 'O') {
    					board[i][j] = 'X';
    				}
    			}
    		}
    	}
    
    	private void dfs(char[][] board, int i, int j) {
    		if (i < 0 || j < 0 || i > board.length - 1
    				|| j > board[0].length - 1 || board[i][j] == 'X') {
    			return;
    		}
    		if (board[i][j] == 'y') {
    			return ;
    		}
    		board[i][j] = 'y';
    		dfs(board, i + 1, j);
    		dfs(board, i - 1, j);
    		dfs(board, i, j - 1);
    		dfs(board, i, j + 1);
    	}
    }
    

    2. BFS (AC)

    public class Solution {
        public void solve(char[][] board) {
    		if (board == null || board.length <= 2 || board[0].length <= 2) {
    			return;
    		}
    
    		int rows = board.length, cols = board[0].length;
    		Queue<Integer> queue = new LinkedList<Integer>();
    		for (int j = 0; j < cols; j++) {
    			bfs(board, 0, j, queue);
    			bfs(board, rows - 1, j, queue);
    		}
    		for (int i = 0; i < rows; i++) {
    			bfs(board, i, 0, queue);
    			bfs(board, i, cols - 1, queue);
    		}
    		for (int i = 0; i < rows; i++) {
    			for (int j = 0; j < cols; j++) {
    				if (board[i][j] == 'y') {
    					board[i][j] = 'O';
    				} else if (board[i][j] == 'O') {
    					board[i][j] = 'X';
    				}
    			}
    		}
    	}
    
    	private void bfs(char[][] board, int i, int j, Queue<Integer> queue) {
    		fillBoard(board, i, j, queue);
    		while (!queue.isEmpty()) {
    			int idx = queue.poll();
    			int r = idx / board[0].length;
    			int c = idx % board[0].length;
    			fillBoard(board, r - 1, c, queue);
    			fillBoard(board, r + 1, c, queue);
    			fillBoard(board, r, c - 1, queue);
    			fillBoard(board, r, c + 1, queue);
    		}
    	}
    
    	private void fillBoard(char[][] board, int i, int j, Queue<Integer> queue) {
    		if (i < 0 || j < 0 || i >= board.length || j >= board[0].length
    				|| board[i][j] == 'X') {
    			return;
    		}
    		if (board[i][j] == 'y') {
    			return;
    		}
    		board[i][j] = 'y';
    		queue.offer(i * board[0].length + j);
    	}
    }
    

    拓展题

    题目地址:http://ac.jobdu.com/problem.php?pid=1335
    题目描述:

    sun所在学校每年都要举行电脑节,今年电脑节有一个新的趣味比赛项目叫做闯迷宫。
    sun的室友在帮电脑节设计迷宫,所以室友就请sun帮忙计算下走出迷宫的最少步数。
    知道了最少步数就可以辅助控制比赛难度以及去掉一些没有路径到达终点的map。
    比赛规则是:从原点(0,0)开始走到终点(n-1,n-1),只能上下左右4个方向走,只能在给定的矩阵里走。

    输入:

    输入有多组数据。
    每组数据输入n(0<n<=100),然后输入n*n的01矩阵,0代表该格子没有障碍,为1表示有障碍物。
    注意:如果输入中的原点和终点为1则这个迷宫是不可达的。

    输出:

    对每组输入输出该迷宫的最短步数,若不能到达则输出-1。

    样例输入:
    2
    0 1
    0 0
    5
    0 0 0 0 0
    1 0 1 0 1
    0 0 0 0 0
    0 1 1 1 0
    1 0 1 0 0
    样例输出:
    2
    8

    解决思路

    求最短路径一般使用BFS.

    程序

    public int minSteps(int[][] maze) {
    		if (maze == null || maze.length == 0 || maze[0].length == 0) {
    			return 0;
    		}
    
    		int m = maze.length, n = maze[0].length;
    		if (maze[0][0] == 1 || maze[m - 1][n - 1] == 1) {
    			return -1;
    		}
    
    		int minSteps = 0;
    		Queue<Integer> queue = new LinkedList<Integer>();
    		queue.offer(0);
    
    		int[][] directions = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };
    
    		while (!queue.isEmpty()) {
    			int size = queue.size();
    			for (int i = 0; i < size; i++) {
    				int idx = queue.poll();
    				int r = idx / n;
    				int c = idx % n;
    				if (r == m - 1 && c == n - 1) {
    					return minSteps;
    				}
    				for (int[] dir : directions) {
    					bfsHelper(maze, r + dir[0], c + dir[1], queue);
    				}
    			}
    			++minSteps;
    		}
    
    		return -1;
    	}
    
    	private void bfsHelper(int[][] maze, int r, int c, Queue<Integer> queue) {
    		if (r < 0 || c < 0 || r >= maze.length || c >= maze[0].length
    				|| maze[r][c] == 1 || maze[r][c] == -1) {
    			return;
    		}
    		maze[r][c] = -1;
    		queue.offer(r * maze[0].length + c);
    	}
    
  • 相关阅读:
    游戏系统开发笔记(八)——场景对象管理
    dynomite:高可用多数据中心同步
    VBS错误代码释义
    VBScript 内置函数
    在oracle中,select语句查询字段中非纯数字值
    ASP里面令人震撼地自定义Debug类(VBScript)
    调试 ASP 程序脚本
    多文档界面的实现(DotNetBar的superTabControl)
    C#利用tabControl控件实现多窗体嵌入及关闭
    使用MDI窗体实现多窗口效果
  • 原文地址:https://www.cnblogs.com/harrygogo/p/4739394.html
Copyright © 2011-2022 走看看