【130-Surrounded Regions(围绕区域)】


【LeetCode-面试算法经典-Java实现】【全部题目文件夹索引】

原题

  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

题目大意

  一个二维网格。包括’X’与’O’。将所以被X包围的O区域用X替代,返回替代后后结果。

解题思路

  採用广度优先遍历的方式。(也能够採用尝试深度优先的方式(会有栈溢出)),标记出全部的被包围的点,剩下的就是不被包围的点

代码实现

算法实现类

import java.util.LinkedList;
import java.util.List; public class Solution {
////////////////////////////////////////////////////////////////////////////////////////////////
// 以下採用广度度优先遍历的方式,找出全部的【不】被包围的点
////////////////////////////////////////////////////////////////////////////////////////////////
public void solve(char[][] board) {
// 參数校验
if (board == null || board.length < 1 || board[0].length < 1) {
return;
} boolean[][] visited = new boolean[board.length][board[0].length];
// 广度优先搜索时外围一圈的元素
List<Coordinate> round = new LinkedList<>();
// 处理顶部行
for (int col = 0; col < board[0].length; col++) {
// 顶部行,而且点是O而且点未被訪问过
if (!visited[0][col] && board[0][col] == 'O') {
round.clear();
round.add(new Coordinate(0, col));
bfs(board, visited, round);
}
} // 处理底部行
for (int col = 0; col < board[0].length; col++) {
// 顶部行,而且点是O而且点未被訪问过
if (!visited[board.length - 1][col] && board[board.length - 1][col] == 'O') {
round.clear();
round.add(new Coordinate(board.length - 1, col));
bfs(board, visited, round);
}
} // 处理左边列
for (int row = 1; row < board.length - 1; row++) {
// 顶部行,而且点是O而且点未被訪问过
if (!visited[row][0] && board[row][0] == 'O') {
round.clear();
round.add(new Coordinate(row, 0));
bfs(board, visited, round);
}
} // 处理右边列
for (int row = 1; row < board.length - 1; row++) {
// 顶部行,而且点是O而且点未被訪问过
if (!visited[row][board[0].length - 1] && board[row][board[0].length - 1] == 'O') {
round.clear();
round.add(new Coordinate(row, board[0].length - 1));
bfs(board, visited, round);
}
} // 标记网格
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
// 假设未被訪问过,有两种可能,第一是X点,第二是O点。O点一定是被X包围的
// 此时将未訪问过的点设置为X是正确的
if (!visited[i][j]) {
board[i][j] = 'X';
}
}
}
} /**
* 深度优先,找不被包围的点
*
* @param board 二维网格
* @param visited 訪问标记数组
* @param round 广度优先搜索时外围一圈的元素
*/
public void bfs(char[][] board, boolean[][] visited, List<Coordinate> round) {
Coordinate c;
while (round.size() > 0) {
c = round.remove(0);
if (c.x >= 0 && c.x < board.length && c.y >= 0 && c.y < board[0].length && board[c.x][c.y] == 'O' && !visited[c.x][c.y]) {
visited[c.x][c.y] = true;
round.add(new Coordinate(c.x - 1, c.y));
round.add(new Coordinate(c.x, c.y + 1));
round.add(new Coordinate(c.x + 1, c.y));
round.add(new Coordinate(c.x, c.y - 1));
}
}
} ////////////////////////////////////////////////////////////////////////////////////////////////
// 以下採用广度度优先遍历的方式,找出全部的被包围的点,而且标记会超时
////////////////////////////////////////////////////////////////////////////////////////////////
public void solve2(char[][] board) {
// 參数校验
if (board == null || board.length < 1 || board[0].length < 1) {
return;
} boolean[][] visited = new boolean[board.length][board[0].length]; // 广度优先搜索时外围一圈的元素
List<Coordinate> round = new LinkedList<>();
// 广度优先搜索进的全部元素
List<Coordinate> all = new LinkedList<>(); for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (!visited[i][j] && board[i][j] == 'O') {
// 广度优先搜索第一圈的元素
round.add(new Coordinate(i, j));
boolean result = bfs(board, visited, round, all);
// 一次搜索的全部O都在网格内,而且不在边界上
if (result) {
// 设置标记
for (Coordinate c : all) {
board[c.x][c.y] = 'X';
}
} // 清空元素
round.clear();
all.clear();
}
}
} } /**
* 广度优先遍历
*
* @param board 二维网格
* @param visited 訪问标记数组
* @param round 广度优先搜索时外围一圈的元素
* @param all 广度优先搜索进的全部元素
* @return true点是O,点在网格内,而且不在边界上,假设点是X。总返回true
*/
public boolean bfs(char[][] board, boolean[][] visited, List<Coordinate> round, List<Coordinate> all) {
boolean result = true;
int size = round.size();
Coordinate c;
while (size > 0) {
size--; // 取队首元素
c = round.remove(0);
// 加入到遍历记录元素集合中
all.add(c);
// 标记已经被訪问过了
visited[c.x][c.y] = true;
// 推断c是否是O内点
result &= isInner(board, c.x, c.y); // c的上面一个点是否是O。而且没有訪问过。满足就加入到round队列中
if (isO(board, c.x - 1, c.y) && !visited[c.x - 1][c.y]) {
round.add(new Coordinate(c.x - 1, c.y));
} // c的右面一个点是否是O。而且没有訪问过,满足就加入到round队列中
if (isO(board, c.x, c.y + 1) && !visited[c.x][c.y + 1]) {
round.add(new Coordinate(c.x, c.y + 1));
} // c的以下一个点是否是O。而且没有訪问过,满足就加入到round队列中
if (isO(board, c.x + 1, c.y) && !visited[c.x + 1][c.y]) {
round.add(new Coordinate(c.x + 1, c.y));
} // c的左面一个点是否是O,而且没有訪问过。满足就加入到round队列中
if (isO(board, c.x, c.y - 1) && !visited[c.x][c.y - 1]) {
round.add(new Coordinate(c.x, c.y - 1));
}
} if (round.size() > 0) {
return bfs(board, visited, round, all) && result;
} else {
return result;
} } /**
* 推断点在二维风格内部,而且不在边界上
*
* @param board 二维网格
* @param x 横坐标
* @param y 纵坐标
* @return true是
*/
public boolean isInner(char[][] board, int x, int y) {
return x > 0 && x < board.length - 1 && y > 0 && y < board[0].length - 1;
} /**
* 推断点是否是O
*
* @param board 二维网格
* @param x 横坐标
* @param y 纵坐标
* @return true是
*/
public boolean isO(char[][] board, int x, int y) {
return x >= 0 && x < board.length && y >= 0 && y < board[0].length && board[x][y] == 'O';
} /**
* 坐标对象
*/
public static class Coordinate {
private int x;
private int y; public Coordinate() {
} public Coordinate(int x, int y) {
this.x = x;
this.y = y;
} @Override
public String toString() {
return "(" + x + ", " + y + ")";
}
}
}

评測结果

  点击图片,鼠标不释放。拖动一段位置,释放后在新的窗体中查看完整图片。

特别说明

欢迎转载。转载请注明出处【http://blog.csdn.net/derrantcm/article/details/47678211

【LeetCode-面试算法经典-Java实现】【130-Surrounded Regions(围绕区域)】的更多相关文章

  1. [LeetCode] 130. Surrounded Regions 包围区域

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

  2. 130. Surrounded Regions(周围区域问题 广度优先)(代码未完成!!)

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

  3. 【LeetCode-面试算法经典-Java实现】【139-Word Break(单词拆分)】

    [139-Word Break(单词拆分)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a string s and a dictionary of w ...

  4. 【LeetCode-面试算法经典-Java实现】【053-Maximum Subarray(最大子数组和)】

    [053-Maximum Subarray(最大子数组和)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Find the contiguous subarray w ...

  5. 【LeetCode-面试算法经典-Java实现】【062-Unique Paths(唯一路径)】

    [062-Unique Paths(唯一路径)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 A robot is located at the top-left c ...

  6. 【LeetCode-面试算法经典-Java实现】【059-Spiral Matrix II(螺旋矩阵II)】

    [059-Spiral Matrix II(螺旋矩阵II)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given an integer n, generate a ...

  7. 【LeetCode-面试算法经典-Java实现】【136-Single Number(仅仅出现一次的数字)】

    [136-Single Number(仅仅出现一次的数字)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given an array of integers, ev ...

  8. 【LeetCode-面试算法经典-Java实现】【075-Sort Colors (颜色排序)】

    [075-Sort Colors (颜色排序)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given an array with n objects colore ...

  9. 【LeetCode-面试算法经典-Java实现】【101-Symmetric Tree(对称树)】

    [101-Symmetric Tree(对称树)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a binary tree, check whether ...

随机推荐

  1. python 进阶:修饰器的介绍

    参考链接:Python 函数装饰器 我认为python中的装饰器是一个很厉害的功能,他能瞬间提升代码的逼格,但对于我这样的小白来说,别说为所欲为的使用了,就连简单的尝试一下,却也是难于登天.经过长达半 ...

  2. Android Recovery OTA升级(一)—— make otapackage

    文件夹 文件夹 概述 make otapackage BUILT_TARGET_FILES_PACKAGE ota_from_target_files WriteFullOTAPackage Sign ...

  3. C++对象模型——效率有了,弹性呢(第七章)

    7.4    效率有了,弹性呢 传统的C++对象模型提供有效率的运行期支持.这份效率,再加上与C之间的兼容性,造成了C++的广泛被接受度.然而,在某些领域方面,像是动态共享函数库(dynamicall ...

  4. 美团实习生电面之谈(成功拿到offer)

    3月底进行了美团的一次实习生面试(Java研发project师).当时顺利的通过一面.以下是我的一面: 1.CPU由哪些部分组成 2.线程和进程的差别 3.Java类载入机制 4.怎样实现一个字符串的 ...

  5. Iocomp控件之数字显示【图文】

    Iocomp关于数字显示有自己的一套方案.并且效果非常棒哦 效果图: 插入控件: 默认效果: 随意改动属性后: 加入变量 调用函数: ); 效果图:

  6. AIX 系统补丁升级步骤

    AIX 系统补丁升级步骤   1.升级之前建议备份 rootvg (推荐) # smit mksysb   2.检查系统版本号 # oslevel -r   3.找到补丁光盘或者下载补丁,上传到服务器 ...

  7. VirtualBox内刚刚安装完CentOS6.9和7系统,无法调整屏幕的分辨率,也无法设置共享文件夹。解决的方法就是安装VirtualBox客户端增强包。

    VirtualBox内刚刚安装完CentOS6.9和7系统,无法调整屏幕的分辨率,也无法设置共享文件夹.解决的方法就是安装VirtualBox客户端增强包. 1.若直接安装客户端增强包会得到如下提示: ...

  8. PHP高手进阶-LAMPer技能树

  9. DEDE 修改后台图集上传单个图片的大小限制

    默认情况下,DEDE图集中单个图片大小限制在2M以内,而有时我们需要上传一个2M以上的文件,这是只要修改几个文件就可以实现了. 一.需要修改php.ini这个文件,我们必须保证PHP的配置中允许上传一 ...

  10. Hexo High一下以及压缩排版问题

    背景介绍 集成Hight一下以及Gulp-html压缩之后出现的问题: High一下功能多次点击,会创建多个Audio对象,导致同时播放多次音乐,重音.解决办法:判断是否添加Audio对象,如果存在则 ...