zoukankan      html  css  js  c++  java
  • [LeetCode] 130. Surrounded Regions

    Medium

    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.

    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
    

    Explanation:

    Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.

    题目大意:给出一个X和O的棋盘,把被X包围的O变成X,在边上的O不算被包围。和边上的O连通的O也不算被包围。

    方法:

    先检索棋盘的四条边,当边上的元素是‘O’时再从这个点开始向内扩张找到所有和他连通的O。先把不被包围的O变成一个特殊符号用于标志,比如变成#,检索完所有元素后再把棋盘中所有的O变成X,#变成O就好了。

    从边上的O向内探索连通的O就用到了DFS。

    方法一:递归DFS

    使用递归的方式完成DFS,代码如下

    class Solution {
    public:
        void solve(vector<vector<char>>& board) {
            if(board.empty() || board[0].empty())return;
            int n=board.size(),m=board[0].size();
            for(int i=0,j=0;j<m;++j){
                if(board[i][j]=='O'){
                  helper(board,i,j);  
                }
            }
            for(int i=0,j=m-1;i<n;++i){
                if(board[i][j]=='O'){
                  helper(board,i,j);  
                }
            }
            for(int i=n-1,j=m-1;j>=0;--j){
                if(board[i][j]=='O'){
                  helper(board,i,j);  
                }
            }
            for(int i=n-1,j=0;i>=0;--i){
                if(board[i][j]=='O'){
                  helper(board,i,j);  
                }
            }
            for(int i=0;i<n;++i){
                for(int j=0;j<m;++j){
                    if(board[i][j]=='#'){board[i][j]='O';}
                    else if(board[i][j]=='O'){board[i][j]='X';}
                }
            }
            return;
        }
        void helper(vector<vector<char>> &board,int i,int j){
            board[i][j]='#';
            if(i>0 && board[i-1][j]=='O'){helper(board,i-1,j);}
            if(i<board.size()-1 && board[i+1][j]=='O'){helper(board,i+1,j);}
            if(j>0 && board[i][j-1]=='O'){helper(board,i,j-1);}
            if(j<board[i].size()-1 && board[i][j+1]=='O'){helper(board,i,j+1);}
        }
    };

    方法二:迭代DFS

    使用队列queue记录连通的O的位置,然后检索他的上下左右各位是不是O,是的话就把他记录成#,并把他的位置也放入队列中,等待检索。

    代码如下:

    class Solution {
    public:
        void solve(vector<vector<char>>& board) {
          if(board.empty() || board[0].empty())return;
          int n = board.size(), m = board[0].size();
          vector<vector<int>> director = { {0,1},{1,0},{0,-1},{-1,0} };
          int i = 0, j = 0;
          queue<int> q;
          for (auto d : director) {
             while (i >= 0 && i < board.size() && j >= 0 && j < board[i].size()) {
                if (board[i][j] == 'O') { 
                    board[i][j] = '#';
                    q.push(i*n+j); 
                 }
                 i = i + d[0], j = j + d[1];
              }
              if (i < 0) { i = 0; }
              if (i >= board.size()) { i = board.size() - 1; }
              if (j < 0) { j = 0; }
              if (j >= board[i].size()) { j = board[i].size() - 1; }
          }
          while (!q.empty()) {
             int x = q.front() / n, y = q.front() % n;
              q.pop();
              if (x > 0 && board[x - 1][y] == 'O') {
                 board[x-1][y] = '#';
                 q.push((x - 1)*n + y);
              }
              if (y > 0 && board[x][y - 1] == 'O') {
                 board[x][y - 1] = '#';
                 q.push(x*n + y - 1);
              }
              if (x < board.size()-1 && board[x+1][y] == 'O') {
                 board[x + 1][y] = '#';
                 q.push((x + 1)*n + y);
              }
              if (y < board.size() - 1 && board[x][y + 1] == 'O') {
                 board[x][y + 1] = '#';
                 q.push(x*n + y + 1);
              }
          }
          for (int i = 0; i < n; ++i) {
             for (int j = 0; j < m; ++j) {
                 if (board[i][j] == '#') { board[i][j] = 'O'; }
                 else if (board[i][j] == 'O') { board[i][j] = 'X'; }
             }
          }
          return;
      }
    };
  • 相关阅读:
    数组中重复的数字
    第一个只出现一次的字符位置
    丑数
    字符串的排列
    把数组排成最小的数
    圆圈中最后剩下的数
    同步通信与异步通信
    S3C2440 UART串口驱动
    ARM处理器工作模式
    s3c2440系统时钟
  • 原文地址:https://www.cnblogs.com/cff2121/p/11671282.html
Copyright © 2011-2022 走看看