【一天一道LeetCode】#130. Surrounded Regions

一天一道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>> temp_stack;//用堆栈来存储中间变量
        temp_stack.push(make_pair(i, j));
        board[i][j] = ‘1‘;
        while (!temp_stack.empty())//堆栈不为空就代表没有处理完
        {
            int y = temp_stack.top().first;
            int x = temp_stack.top().second;
            temp_stack.pop();//出栈
            for (int idx = 0; idx < 4; idx++)//处理出栈坐标四个方向是否存在‘O’
            {
                int y0 = y + Y[idx];
                int x0 = x + X[idx];
                if (y0 >= 0 && y0 < row&&x0 >= 0 && x0 < col)
                {
                    if (board[y0][x0] == ‘O‘)//为‘O‘就压栈等待后续处理
                    {
                        board[y0][x0] = ‘1‘;
                        temp_stack.push(make_pair(y0, x0));
                    }
                }
            }
        }
    }
};

提交代码,AC,16ms!

更多关于递归和迭代的转换可以参考本人的这篇博文:【数据结构与算法】深入浅出递归和迭代的通用转换思想

时间: 2024-10-07 17:36:01

【一天一道LeetCode】#130. Surrounded Regions的相关文章

leetcode 130 Surrounded Regions(BFS)

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

Java for LeetCode 130 Surrounded Regions

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 XX O O XX X O XX O X X After running your function, the board should be:

[LeetCode]130 Surrounded Regions(DFS)

题目链接:https://leetcode.com/problems/surrounded-regions/?tab=Description 题意:把非边界的O改成X. 先dfs边界的,打好标记.把没变的变成X后同时更新标记的为O. 1 class Solution { 2 public: 3 const int dx[5] = {0, 0, 1, -1}; 4 const int dy[5] = {1, -1, 0, 0}; 5 int n, m; 6 bool ok(int x, int y

leetcode[130] Surrounded Regions

给定一个类似棋盘,有X和O,把X圈住的O变为X例如: 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,然后和四周的O相邻的O全都是不可能转化为X的,我们用另外一个符号标记,那么最后,矩阵中的O就是被圈住的,就需要转化为X,然后其他标记的符号就要转为原来的O.

Leetcode 130 Surrounded Regions DFS

将内部的O点变成X input X X X XX O O X X X O XX O X X output X X X XX X X XX X X XX O X X DFS图所有边上的点,将边上的O以及其联通域变为T,然后将内部的O变为X,外部的T变为O,本质是种子填充算法. 此题对于is_in这个函数要注意, 不要用(x < m) && (x >= 0) && (y < n) && (y >= 0) 会堆栈溢出!!原因是会出现边上的点

LeetCode OJ - Surrounded Regions

我觉得这道题和传统的用动规或者贪心等算法的题目不同.按照题目的意思,就是将被'X'围绕的'O'区域找出来,然后覆盖成'X'. 那问题就变成两个子问题: 1. 找到'O'区域,可能有多个区域,每个区域'O'都是相连的: 2. 判断'O'区域是否是被'X'包围. 我采用树的宽度遍历的方法,找到每一个'O'区域,并为每个区域设置一个value值,为0或者1,1表示是被'X'包围,0则表示不是.是否被'X'包围就是看'O'区域的边界是否是在2D数组的边界上. 下面是具体的AC代码: class Boar

leetcode --day12 Surrounded Regions &amp; Sum Root to Leaf Numbers &amp; Longest Consecutive Sequence

1.  Surrounded Regions 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 fu

[LeetCode][JavaScript]Surrounded Regions

Surrounded Regions 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

【LeetCode】 Surrounded Regions (BFS &amp;&amp; DFS)

题目:Surrounded Regions 广搜和深搜都能解决,但是LeetCode上使用深搜时会栈溢出 DFS: <span style="font-size:18px;">/*LeetCode Surrounded Regions * 题目:给定一个字符数组,由'X'和'O'组成,找到所有被x包围的o并将其替换为x * 思路:只要替换被包围的o就行,如果有一个o是边界或者上下左右中有一个是o且这个o不会被替换,则该点也不会被替换 * 从四条边开始,因为在这4周的一定不是