题目:

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的更多相关文章

  1. hdu 4739【位运算】.cpp

    题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...

  2. 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~ ...

  3. 【Valid Sudoku】cpp

    题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...

  4. 【Permutations II】cpp

    题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...

  5. 【Subsets II】cpp

    题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...

  6. 【Sort Colors】cpp

    题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...

  7. 【Sort List】cpp

    题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...

  8. 【Path Sum】cpp

    题目: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up ...

  9. 【Symmetric Tree】cpp

    题目: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). F ...

随机推荐

  1. Keymob带你玩转新广告法下的移动营销

    2015年9月1日新广告法正式实施,对广告代言人.广告类别.广告语等都做了一系列新规定,堪称有史以来最严广告法.随着新广告法的实施,以往一些庸俗.夸张的广告也逐渐和大众说再见了. 2015年 “互联网 ...

  2. 【Shell脚本学习23】Shell函数参数

    在Shell中,调用函数时可以向其传递参数.在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数... 带参数的函数示例: #!/bin/bash funWit ...

  3. winform 自适应屏幕分辨率具体操作和注意事项

    第一步:先借助一个类文件 AutoSizeFormClass.cs class AutoSizeFormClass { public struct controlRect { public int L ...

  4. [:space:]的用法(转)

    转自:http://blog.itpub.net/27181165/viewspace-1061688/ 在linux中通常会使用shell结合正则表达式来过滤字符,本文将以一个简单的例子来说明+,* ...

  5. 第1章 .Net应用程序体系结构

    1. CLR:公共语言运行库,是每种.Net编程语言都使用的运行库 Windows 8为Windows Store应用程序引入了一个新的编程接口:Windows运行库. C# 6 具有许多小而实用的语 ...

  6. vue+node+mongodb实现的页面

    源代码地址:https://github.com/GainLoss/vue-node-mongodb 目前这个项目实现的是: 1.利用vue-cli实现前台页面的编写 (1)页面的跳转利用的是vue- ...

  7. java核心技术 要点笔记3

    1.类,超类和子类 2.Object:所有类的超类 3.泛型数组列表 4.对象包装器和自动装箱 5.参数数量可变的方法 6.枚举类 7.反射 8.继承设计的技巧

  8. ffmpeg 命令2

    ffmpeg常用基本命令(转) [FFmpeg]FFmpeg常用基本命令 1.分离视频音频流 ffmpeg -i input_file -vcodec copy -an output_file_vid ...

  9. 【洛谷2279】[HNOI2003] 消防局的设立(贪心)

    点此看题面 大致题意: 给你\(N\)个点(其中\(1\)号点为根),并告诉你编号为\(2\sim N\)的点的父亲(\(fa[i]<i\)),现在要在树上选择尽量少的关键点(消防局),使得任意 ...

  10. ETL工具--DataX3.0实战

    DataX是一个在异构的数据库/文件系统之间高速交换数据的工具,实现了在任意的数据处理系统(RDBMS/Hdfs/Local filesystem)之间的数据交换,由淘宝数据平台部门完成. DataX ...