【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. golang实现php里的serialize()和unserialize()序列和反序列方法

    Golang 实现 PHP里的 serialize() . unserialize() 安装 go get -u github.com/techleeone/gophp/serialize 用法 pa ...

  2. Linux学习总结(9)——Linux 新手必知必会的 10 条 Linux 基本命令

    Linux 对我们的生活产生了巨大的冲击.至少你的安卓手机使用的就是 Linux 核心.尽管如此,在第一次开始使用 Linux 时你还是会感到难以下手.因为在 Linux 中,通常需要使用终端命令来取 ...

  3. 修改MySQL默认字符集

    今天发现有库级字符集和表级字符集,实验了下发现,库级字符集是该库内表的默认字符集,当创建表时,如果未指定字符集,默认使用该表所属库的字符集.表也可使用不同于所属库的字符集. MySQL对于字符集的指定 ...

  4. ArcGIS api for javascript——渲染-计算相等间隔分级

    描述 本例展示了如何配置分级渲染使用一个相等间隔分类.在这个分类类型中,断点被设置为相等的距离. 可以手工添加相等距离的断点:然而,如果数据被修改了,那些断点就会是不合理的.本例自动地计算断点,因此相 ...

  5. cocos2d-x 2.2.0 怎样在lua中注冊回调函数给C++

    cocos2d-x内部使用tolua进行lua绑定.可是引擎并没有提供一个通用的接口让我们能够把一个lua函数注冊给C++层面的回调事件. 翻看引擎的lua绑定代码,我们能够仿照引擎中的方法来做. 值 ...

  6. FPGA design flow

    FPGA engineering process usually involves the following stages: Architecture design. This stage invo ...

  7. HtmlHelper的扩展分页方法

    一.新建一个空MVC项目,命名为MVCAppPager 二.新建一个文件夹PageHelper,在文件夹下新建接口IPageList以及实现类PageList IPageList接口: public ...

  8. OPENCV(4) —— ImgProc

    2D图像滤波器基础类BaseFilter:dst(x,y) = F(src(x,y), src(x+1,y)... src(x+wdith-1,y), src(y+1,x)... src(x+widt ...

  9. Object和其他类型的转换

    Object对象是一切类的父类(基类),只要是Object对象,可以强制转换为其他类型.

  10. linux下pptp配置步骤

    最近买了个VPS,于是随手搭了个VPN玩,ubuntu安装pptp太蠢了,直接apt-install pptp就行了 1./etc/pptpd.conf 注销最后两行,就是设置IP转发的范围,给那么几 ...