leetcode 130. Surrounded Regions 典型的深度优先遍历DFS + 矩阵遍历
2017-09-16 13:07
357 查看
Given a 2D board containing ‘X’ and ‘O’ (the letter 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
从矩形最外面一圈开始逐渐向里拓展。 若 O 是在矩形最外圈,它肯定不会被 X 包围,与它相连(邻)的 O 也就不可能被 X 包围,也就不会被替换,所以我们的工作主要是找出:
1)最外圈的 O
2)与最外圈的 O 相连的 O
3) 将上述找到的元素替换为某种标识符,代码中使用“#”
4.)最后按先行后列的顺序遍历矩形,找到没有被替换为 O 的元素,它们就是被 X 完全包围的需要被替换为 X 的元素;同时,标记为 # 的元素是没有被 X 包围的元素,此时将它们变回原来的 O
这道题的亮点是从问题的对立面来考虑做得,是很经典的DFS深度优先遍历的做法,很棒
代码如下:
下面是C++的做法,就是做一个DFS深度优先遍历,不过这道题我们是反其道而行之,通过寻找不符合条件的O,标记为*,然后把剩下的O填充为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
从矩形最外面一圈开始逐渐向里拓展。 若 O 是在矩形最外圈,它肯定不会被 X 包围,与它相连(邻)的 O 也就不可能被 X 包围,也就不会被替换,所以我们的工作主要是找出:
1)最外圈的 O
2)与最外圈的 O 相连的 O
3) 将上述找到的元素替换为某种标识符,代码中使用“#”
4.)最后按先行后列的顺序遍历矩形,找到没有被替换为 O 的元素,它们就是被 X 完全包围的需要被替换为 X 的元素;同时,标记为 # 的元素是没有被 X 包围的元素,此时将它们变回原来的 O
这道题的亮点是从问题的对立面来考虑做得,是很经典的DFS深度优先遍历的做法,很棒
代码如下:
import java.util.Stack; class Point { int row; int col; Point(int a,int b) { row = a; col =b; } } /* * 这个用来学习BFS和DFS很有用 * * 本题是要求把所有的内部的O替换为X,但是矩阵边界的O不算, * 本题是从反面来考虑的,把所有不能替换的O使用*来做一个标记 * * 本题是通过stack来完成深度优先遍历的,使用BFS或者递归去做 * 是同样的做法 * * */ public class Solution { public void solve(char[][] board) { if(board==null || board.length<=0) return; int row = board.length; int col = board[0].length; if(row<=2 || col<=2) return; boolean [][]visit = new boolean[row][col]; for(int i=0;i<row;i++) { for(int j=0;j<col;j++) { if(board[i][j]=='O') { if(i==0||i==row-1 ||j==0||j==col-1) dfs(visit,board,i,j,row,col); } } } for(int i=0;i<row;i++) { for(int j=0;j<col;j++) { if(board[i][j]=='*') board[i][j]='O'; else if(board[i][j]=='O') board[i][j]='X'; } } } private void dfs(boolean [][]visit,char[][] board, int x, int y, int row, int col) { board[x][y]='*'; Stack<Point> stack = new Stack<>(); stack.push(new Point(x,y)); visit[x][y]=true; while(stack.empty()==false) { Point top = stack.peek(); stack.pop(); if(top.row>0 && board[top.row-1][top.col]=='O' && visit[top.row-1][top.col]==false) { board[top.row-1][top.col]='*'; visit[top.row-1][top.col]=true; stack.push(new Point(top.row-1, top.col)); } if(top.row+1<row && board[top.row+1][top.col]=='O' && visit[top.row+1][top.col]==false) { board[top.row+1][top.col]='*'; visit[top.row+1][top.col]=true; stack.push(new Point(top.row+1, top.col)); } if(top.col>0 && board[top.row][top.col-1]=='O' && visit[top.row][top.col-1]==false) { board[top.row][top.col-1]='*'; visit[top.row][top.col-1]=true; stack.push(new Point(top.row, top.col-1)); } if(top.col+1<col && board[top.row][top.col+1]=='O' && visit[top.row][top.col+1]==false) { board[top.row][top.col+1]='*'; visit[top.row][top.col+1]=true; stack.push(new Point(top.row, top.col+1)); } } } }
下面是C++的做法,就是做一个DFS深度优先遍历,不过这道题我们是反其道而行之,通过寻找不符合条件的O,标记为*,然后把剩下的O填充为X即可完成本体的所有要求
代码如下:
#include <iostream> #include <vector> #include <map> #include <unordered_map> #include <set> #include <unordered_set> #include <queue> #include <stack> #include <string> #include <climits> #include <algorithm> #include <sstream> #include <functional> #include <bitset> #include <numeric> #include <cmath> #include <regex> #include <iomanip> #include <cstdlib> #include <ctime> using namespace std; class Solution { public: void solve(vector<vector<char>>& b) { if (b.size() <= 0) return; int row = b.size(), col = b[0].size(); vector<vector<bool>> visit(row, vector<bool>(col, false)); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (i == 0 || i == row - 1 || j == 0 || j == col - 1) dfs(b,visit, i, j); } } for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (b[i][j] == 'O') b[i][j] = 'X'; else if(b[i][j] == '*') b[i][j] = 'O'; } } } void dfs(vector<vector<char>>& b, vector<vector<bool>>& visit, int x, int y) { int row = b.size(), col = b[0].size(); if (x < 0 || x >= row || y < 0 || y >= col || visit[x][y] == true || b[x][y] != 'O') return; else { visit[x][y] = true; b[x][y] = '*'; dfs(b, visit, x - 1, y); dfs(b, visit, x + 1, y); dfs(b, visit, x, y - 1); dfs(b, visit, x, y + 1); } } };
相关文章推荐
- leetcode 329. Longest Increasing Path in a Matrix 矩阵中寻找最长递增序列 + 一个典型的深度优先遍历DFS的做法
- leetcode 695. Max Area of Island 岛屿的最大面积 + 十分典型的深度优先遍历DFS
- leetcode 547. Friend Circles 寻找图的环的数量 + 典型的深度优先遍历DFS
- leetcode 399. Evaluate Division 等式求解+典型的DFS深度优先遍历
- leetcode 752. Open the Lock 开锁 + 十分典型的广度优先遍历BFS
- leetcode 491. Increasing Subsequences所有的递增序列 + 一个典型的深度优先遍历DFS的做法
- LeetCode 463. Island Perimeter (算法, 矩阵遍历)
- leetcode 498. Diagonal Traverse 矩阵对角遍历 + 控制方向即可
- leetcode 638. Shopping Offers 最佳购物优惠+十分典型深度优先遍历DFS
- LeetCode 561. Array Partition I (排序、遍历)
- leetcode 515. Find Largest Value in Each Tree Row 二叉树每一层最大值+广度优先遍历BFS
- leetcode 282. Expression Add Operators 任意添加运算符计算结果 +深度优先遍历DFS
- LeetCode之二叉树的遍历(二)
- Delphi下实现全屏快速找图找色 二、矩阵遍历
- [LeetCode]106 根据中序遍历和后序遍历构建二叉树
- LeetCode 637 Average of Levels in Binary Tree(二叉树层序遍历)
- lintcode--平面范围求和-不可变矩阵(leetcode--Range Sum Query 2D)
- LeetCode 73. Set Matrix Zeros(矩阵赋零)
- leetcode 343. Integer Break 深度优先遍历DFS(超时) + 最大子元素乘积 + 发现规律
- [Leetcode-94中序-144前序-145后序]【Stack】递归和非递归方式遍历二叉树