Skip to content

Latest commit

 

History

History
executable file
·
254 lines (122 loc) · 8.04 KB

130. Surrounded Regions.md

File metadata and controls

executable file
·
254 lines (122 loc) · 8.04 KB

#

一天一道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 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

##(二)解题

本题大意:棋盘上放满了‘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>> q;

    q.push(make_pair(i, j));

    board[i][j] = '1';

    

    while (!q.empty())

    {

    int y = q.top().first;

    int x = q.top().second;

    

    q.pop();

    

    for (int idx = 0; idx < 4; idx++)

    {

    int y0 = y + Y[idx];

    int x0 = x + X[idx];

    

    if (y0 >= 0 && y0 < row&&x0 >= 0 && x0 < col)

    {

        if (board[y0][x0] == 'O')

        {

        board[y0][x0] = '1';

        q.push(make_pair(y0, x0));

        }

    }

    }

    }

    }

};



提交代码,AC,16ms!