【一天一道LeetCode】#130. Surrounded Regions
一天一道LeetCode
本系列文章已全部上传至我的github,地址:ZeeCoder‘s Github
欢迎大家关注我的新浪微博,我的新浪微博
欢迎转载,转载请注明出处
(一)题目
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 XAfter 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’
需要注意被’X‘包围必须是上下左右都被包围。
这道题我最开始的做法是:遍历整个棋盘,当碰到一个’O‘之后,就采用广度搜索的方法,从上下左右四个方向上进行搜索,为’O‘就标记下来,如果搜索过程中碰到边界就代表此范围不能被’X‘包围,就不做处理;反之,如果没有碰到边界就把标记下来的’O‘全部转换成’X‘。
这种做法不好之处就是:需要找遍棋盘中所有的’O‘集合。
于是就采用逆向思维,从边界出发,已经判定这块’O’集合为不被’X‘包围的集合,这样就大大减少了搜索量。
class Solution {
public:
void solve(vector<vector<char>>& board) {
if(board.empty()) return;
int row = board.size();
int col = board[0].size();
for(int i = 0 ; i < row ; i++)//从左、右边界开始往里面搜
{
if(board[i][0]=='O') isSurroundendBy(board,row,col,i,0);
if(board[i][col-1]=='O') isSurroundendBy(board,row,col,i,col-1);
}
for(int i = 1 ; i < col-1 ; i++)//从上、下边界开始往里面搜
{
if(board[0][i]=='O') isSurroundendBy(board,row,col,0,i);
if(board[row-1][i]=='O') isSurroundendBy(board,row,col,row-1,i);
}
for(int i = 0 ; i < row ; i++)//遍历棋盘,将标记的’1‘还原成’O‘,将’O‘改写成’X‘
{
for(int j = 0 ; j < col ;j++)
{
if(board[i][j] == 'O') board[i][j] = 'X';
else if(board[i][j] == '1') board[i][j] = 'O';
}
}
}
void isSurroundendBy(vector<vector<char>>& board, int& row, int& col, int i, int j)
{
if(board[i][j] =='O'){
board[i][j] = '1';//标记需要修改的’O‘
//上下左右四个方向搜索
if (i+1<row&&board[i+1][j]=='O') isSurroundendBy(board, row, col, i+1, j);
if (i-1>=0&&board[i-1][j]=='O') isSurroundendBy(board, row, col, i-1, j);
if (j+1<col&&board[i][j+1]=='O') isSurroundendBy(board, row, col, i, j+1);
if (j-1>=0&&board[i][j-1]=='O') isSurroundendBy(board, row, col, i, j-1);
}
}
};
于是兴高采烈的提交代码,结果Runtime Error!
递归的缺点显露出来了,递归深度太深,导致堆栈溢出。
接下来就把递归版本转换成迭代版本,消除递归带来的堆栈消耗。
class Solution {
public:
void solve(vector<vector<char>>& board) {
int row = board.size();
if(row==0) return;
int col = board[0].size();
for(int i = 0 ; i < row ; i++)//从左、右边界开始往里面
{
if(board[i][0]=='O') isSurroundendBy(board,row,col,i,0);
if(board[i][col-1]=='O') isSurroundendBy(board,row,col,i,col-1);//从上、下边界开始往里面
}
for(int i = 0 ; i < col ; i++)
{
if(board[0][i]=='O') isSurroundendBy(board,row,col,0,i);
if(board[row-1][i]=='O') isSurroundendBy(board,row,col,row-1,i);
}
for (int i = 0; i < row; i++)//遍历棋盘修改标记
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == 'O') board[i][j] = 'X';
if (board[i][j] == '1') board[i][j] = 'O';
}
}
}
int X[4] = {-1,0,1,0};//四个方向
int Y[4] = { 0,-1,0,1 };
void isSurroundendBy(vector<vector<char>>& board, int& row, int& col, int i, int j)
{
stack<pair<int, int>> temp_stack;//用堆栈来存储中间变量
temp_stack.push(make_pair(i, j));
board[i][j] = '1';
while (!temp_stack.empty())//堆栈不为空就代表没有处理完
{
int y = temp_stack.top().first;
int x = temp_stack.top().second;
temp_stack.pop();//出栈
for (int idx = 0; idx < 4; idx++)//处理出栈坐标四个方向是否存在‘O’
{
int y0 = y + Y[idx];
int x0 = x + X[idx];
if (y0 >= 0 && y0 < row&&x0 >= 0 && x0 < col)
{
if (board[y0][x0] == 'O')//为'O'就压栈等待后续处理
{
board[y0][x0] = '1';
temp_stack.push(make_pair(y0, x0));
}
}
}
}
}
};
提交代码,AC,16ms!
更多关于递归和迭代的转换可以参考本人的这篇博文:【数据结构与算法】深入浅出递归和迭代的通用转换思想
【一天一道LeetCode】#130. Surrounded Regions的更多相关文章
- [LeetCode] 130. Surrounded Regions 包围区域
Given a 2D board containing 'X' and 'O'(the letter O), capture all regions surrounded by 'X'. A regi ...
- Leetcode 130. Surrounded Regions
Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A reg ...
- Java for LeetCode 130 Surrounded Regions
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...
- leetcode 130 Surrounded Regions(BFS)
Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...
- Leetcode 130 Surrounded Regions DFS
将内部的O点变成X input X X X XX O O X X X O XX O X X output X X X XX X X XX X X XX O X X DFS的基本框架是 void dfs ...
- leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions
两种方式处理已经访问过的节点:一种是用visited存储已经访问过的1:另一种是通过改变原始数值的值,比如将1改成-1,这样小于等于0的都会停止. Number of Islands 用了第一种方式, ...
- 130. Surrounded Regions(M)
130.Add to List 130. Surrounded Regions Given a 2D board containing 'X' and 'O' (the letter O), capt ...
- 【LeetCode】130. Surrounded Regions (2 solutions)
Surrounded Regions Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A ...
- [LeetCode] 130. Surrounded Regions_Medium tag: DFS/BFS
Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A reg ...
随机推荐
- angularjs+ionic的app端分页和条件
做app项目积分商城的商品列表需要分页显示 实现: ionic滚动条:ion-scroll 用于创建一个可滚动的容器. 附:菜鸟教程:http://www.runoob.com/ionic/ionic ...
- 3-学习GPRS_Air202(需要知道的关于Lua的一些基本的知识)
http://www.cnblogs.com/yangfengwu/p/8948935.html 学东西一定是打破沙锅学到底,有问题就解决问题,不要试图去回避或者放弃解决当前的问题,如果总是回避或 ...
- Oracle中的行转列例子详解
--场景1: A B a a a b b 希望实现如下效果: a ,, b , create table tmp as B from dual union all B from dual union ...
- Java并发编程(一)-为什么要并发
并发所带来的好处 1. 并发在某些情况(并不是所有情况)下可以带来性能上的提升 1) 提升对CPU的使用效率 提升多核CPU的利用率:一般来说一台主机上的会有多个CPU核心,我们可以创建多个线程,理论 ...
- Django 跨域请求处理
参考https://blog.csdn.net/qq_27068845/article/details/73007155 http://blog.51cto.com/aaronsa/2071108 d ...
- 微信小程序基础之开源项目库汇总
awesome-github-wechat-weapp 是由OpenDigg整理并维护的微信小程序开源项目库集合.我们会定期同步OpenDigg上的项目到这里,也欢迎各位提交项目给我们. (链接:ht ...
- 《读书报告 -- Elasticsearch入门 》-- 安装以及简单使用(1)
<读书报告 – Elasticsearch入门 > 第一章 Elasticsearch入门 Elasticsearch是一个实时的分布式搜索和分析引擎,使得人们可以在一定规模上和一定速度上 ...
- 安卓高级Fresco图片框架的时候
Fresco:2015FaceBook推出的 及其强大 支持webp图片格式 和渐进式图片加载 中文文档 使用方法 引入依赖 点击查看具体教程 基本使用步骤 在布局中使用其标签 <com.fac ...
- pthon核心编程-读书笔记:知识点摘录与总结(方便理解和快速记忆)
Python 中的列表(大小可变的数组)和字典(哈希表)就是内建于语言本身的.在核心语言中提供这些重要的构建单元,可以鼓励人们使用它们, 缩短开发时间与代码量,产生出可读性更好的代码.C不提供, c+ ...
- cassandra 常见问题
摘要 本文主要介绍在部署cassandra集群以及使用cassandra过程中遇到的一些问题. 文章只发布在CSDN 和个人站点 更多nosql文章可以访问stone fang 个人主页 正文 Q1: ...