【Surrounded Regions】cpp
题目:
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
代码:
class Solution {
public:
void solve(vector<vector<char>>& board) {
const int ROW = board.size();
if ( ROW< ) return;
const int COL = board[].size();
// first row
for ( int i = ; i < COL; ++i )
{if ( board[][i]=='O') { board[][i] = 'M'; Solution::bfs(board, , i, ROW, COL); }}
// last row
for ( int i = ; i < COL; ++i )
{if ( board[ROW-][i]=='O' ) { board[ROW-][i] = 'M'; Solution::bfs(board, ROW-, i, ROW, COL); }}
// first col
for ( int i = ; i < ROW; ++i )
{if ( board[i][]=='O' ) { board[i][] = 'M'; Solution::bfs(board, i, , ROW, COL); }}
// last col
for ( int i = ; i < ROW; ++i )
{if ( board[i][COL-]=='O' ) { board[i][COL-]='M'; Solution::bfs(board, i, COL-, ROW, COL); }}
// flipping surrounded regions
for ( int i = ; i < ROW; ++i ){
for ( int j = ; j < COL; ++j ){
if ( board[i][j]=='O' ) { board[i][j]='X'; continue; }
if ( board[i][j]=='M' ) { board[i][j]='O'; continue; }
}
}
}
static void bfs(vector<vector<char> >& board, int row, int col, int ROW, int COL )
{
queue<pair<int, int> > que;
que.push(make_pair(row, col));
while ( !que.empty() ){
int r = que.front().first, c = que.front().second;
que.pop();
// up left down right
if ( r-> && board[r-][c]=='O' ) { board[r-][c]='M'; que.push(make_pair(r-, c)); }
if ( c-> && board[r][c-]=='O') { board[r][c-]='M'; que.push(make_pair(r, c-)); }
if ( r+<ROW- && board[r+][c]=='O' ) { board[r+][c]='M'; que.push(make_pair(r+, c)); }
if ( c+<COL- && board[r][c+]=='O' ) { board[r][c+]='M'; que.push(make_pair(r, c+)); }
}
}
};
tips:
参考的BFS的思路(http://yucoding.blogspot.sg/2013/08/leetcode-question-131-surrounded-regions.html)
先说大体思路
这个思路正好与常规的思路逆过来:
1. 常规的思路是从wall里面挨个BFS遍历,如果从一个'O'出发的所有点都满足封住了,则这BFS走过的点都被封住了,最后赋值为'X'(这样会超时)
2. 而这道题的思路比较好的是逆过来,从边界的'O'出发BFS(因为只要跟边界的'O'连上了,就必然封不住了;而没有与边界的'O'边界连上的'O'自然被封住了)
再说实现细节:
1. 为了不使用额外空间,对于由边界'O'经BFS得到的'O'都置为'M'(M有两个意思:一是访问过了,不用再访问了;二是这个点再最后要恢复为'O')
2. BFS的时候,终止条件第一次直接写的是que.empty(),一直不对;后来改成了!que.empty()才对,这个低级错误不要再犯。
=========================================
第二次过这道题,有个细节没有注意:
如果发现一个点四周的点是要保留的‘O’时,一定要马上将其设置为‘M’,然后再进行BFS;如果不马上设置为‘M',那么在BFS的过程中,可能会重复过这个点。
class Solution {
public:
void solve(vector<vector<char> >& board)
{
if ( board.size()< ) return;
const int m = board.size();
const int n = board[].size();
// search from first row
for ( int i=; i<n; ++i )
{
if ( board[][i]=='O' ) Solution::bfs(board, , i, m, n);
}
// search from last row
for ( int i=; i<n; ++i )
{
if ( board[m-][i]=='O' ) Solution::bfs(board, m-, i, m, n);
}
// search from first column
for ( int i=; i<m; ++i )
{
if ( board[i][]=='O' ) Solution::bfs(board, i, , m, n);
}
// search from last column
for ( int i=; i<m; ++i )
{
if ( board[i][n-]=='O' ) Solution::bfs(board, i, n-, m, n);
}
// trans 'O' to 'X' & trans 'M' to 'O'
for ( int i=; i<m; ++i )
{
for ( int j=; j<n; ++j )
{
if ( board[i][j]=='O' )
{
board[i][j]='X';
continue;
}
if ( board[i][j]=='M' )
{
board[i][j]='O';
}
}
}
}
static void bfs(vector<vector<char> >& board, int r, int c, int ROW, int COL)
{
board[r][c] = 'M';
queue<pair<int, int> > curr;
queue<pair<int, int> > next;
curr.push(make_pair(r, c));
while ( !curr.empty() )
{
while ( !curr.empty() )
{
int i = curr.front().first;
int j = curr.front().second;
curr.pop();
// up
if ( i->= && board[i-][j]=='O' )
{
board[i-][j] = 'M';
next.push(make_pair(i-, j));
}
// down
if ( i+<ROW && board[i+][j]=='O' )
{
board[i+][j] = 'M';
next.push(make_pair(i+, j));
}
// left
if ( j->= && board[i][j-]=='O' )
{
board[i][j-] = 'M';
next.push(make_pair(i, j-));
}
// right
if ( j+<COL && board[i][j+]=='O' )
{
board[i][j+] = 'M';
next.push(make_pair(i, j+));
}
}
swap(next, curr);
}
}
};
【Surrounded Regions】cpp的更多相关文章
- hdu 4739【位运算】.cpp
题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...
- Hdu 4734 【数位DP】.cpp
题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...
- 【Valid Sudoku】cpp
题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...
- 【Permutations II】cpp
题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...
- 【Subsets II】cpp
题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...
- 【Sort Colors】cpp
题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...
- 【Sort List】cpp
题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...
- 【Path Sum】cpp
题目: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up ...
- 【Symmetric Tree】cpp
题目: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). F ...
随机推荐
- 跨平台移动开发phonegap/cordova 3.3全系列教程-目录
目录(更新完成后会附上源码供参考) 第一章 android平台开发 phonegap/cordova简介 1.开发环境搭建 2.helloworld 3.启动画面 4.结合asp.net/jqmboi ...
- .Net创建Windows服务完成批量导出功能(错误速查)
无法打开计算机“.”上的服务控制管理器.此操作可能需要其他特权. 无法将类型为“Microsoft.Office.Interop.Word.ApplicationClass”的 COM 对象强制转换为 ...
- IOS 线程描述
●什么是线程 ● 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) ● 线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 ● 比如使用酷狗播放音乐.使用迅雷下载电影, ...
- iptables (1) 原理
网上看到这个配置讲解得还比较易懂,就转过来了,大家一起看下,希望对您工作能有所帮助. iptables简介 netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防 ...
- django建议入门-FYI
django 简易博客 现在正式开始博客开发 1安装官方发布版 官方发布的版本带有一个版本号,例如1.0.3或1.1,而最新版本总是可以在http://www.djangoproject.com/do ...
- ARM体系结构与编程-3
ARM存储系统:ARM中用于存储管理的系统控制协处理器CP15:包括16个32位寄存器,其编号为0到15.实际上对于某些编号的寄存器可能相应有多个物理寄存器. 訪问CP15寄存器的指令:MRC.MCR ...
- js中随机数获取
// 结果为0-1间的一个随机数(包括0,不包括1) var randomNum1 = Math.random(); //console.log(randomNum1); // 函数结果为入参的整数部 ...
- 关于java的自增问题
程序执行结果是0,,,因为count永远是0
- shell脚本,awk实现跳过文件里面的空行。
1.用awk '{if(!NF ){next}}1' file11 实现对文件里面的空行进行跳过操作,并输出结果. 2. awk '{if(!NF || /^#/){next}}1' file11 实 ...
- neo4j 安装
查看 http://ip:7474/browser/