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); }