Surrounded Regions

来源:互联网 发布:爱普生l360清零软件 编辑:程序博客网 时间:2024/05/16 11:26

题目

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:

X X X XX X X XX X X XX O X X

 

思路一:深度优先+Flag

深度优先 DFS 遍历矩阵的边缘元素,将O相连的区域赋值为1,其他的为0,在将flag标志为0的board置为X。

实现代码

class Solution {     public:    void solve(vector<vector<char>> &board) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        int rows = board.size();        if(rows<=0)            return;        int cols = board[0].size();        vector<vector<int>> flag(rows,vector<int>(cols,0));                  for(int i=0;i<rows;i++)        {            dfs(i,0,board,flag);            dfs(i,cols-1,board,flag);        }        for(int j=0;j<cols;j++)        {            dfs(0,j,board,flag);            dfs(rows-1,j,board,flag);        }              for(int i=1;i<rows-1;i++)            for(int j=0;j<cols;j++)            {                if(flag[i][j]==0)                    board[i][j]='X';            }        return;          }    void dfs(int i,int j,vector<vector<char>> &board,vector<vector<int>> &flag)    {        int rows = board.size();        int cols = board[0].size();        if(i<0||i>=rows||j<0||j>=cols)            return ;        if(board[i][j]=='X')            return ;          if(board[i][j]=='O' && flag[i][j]==0)        {            flag[i][j]=1;            dfs(i,j-1,board,flag);            dfs(i,j+1,board,flag);            dfs(i+1,j,board,flag);            dfs(i-1,j,board,flag);        }             }};

注意:要对 flag 数组初始化 vector<vector<int>> flag(rows,vector<int>(cols,0));  否则会出现错误。

上述运行结果是 对于 Juge Small 运行正确,但是对于 Juge Large 会出现 Runtime Error 。

因该是 运行时内存溢出,主要是用到了 flag 数组。其实完全不必用到的。下面的改进。

思路二:深度优先 

 1、First scan the four edges of the board, if you meet an 'O', call a recursive mark function to mark that region to something else (for example, '+');

2、scan all the board, if you meet an 'O', flip it to 'X';

3、scan again the board, if you meet an '+', flip it to 'O';

step 2 and 3 can be merged.

然后我实现的代码如下:

class Solution {         public:        void dfs(int i,int j,vector<vector<char>> &board)        {         if(i<0 || i>=board.size() || j<0 || j>=board[0].size() )              return;          if(board[i][j]=='O')            {                board[i][j]='#';              dfs(i,j+1,board);              dfs(i,j-1,board);              dfs(i-1,j,board);               dfs(i+1,j,board);           }        }      void solve(vector<vector<char>> &board) {            // Start typing your C/C++ solution below            // DO NOT write int main() function            int rows = board.size();            if(rows<=2)              return ;          int cols = board[0].size();                    for(int i=0;i<rows;i++)            {                dfs(i,0,board);                dfs(i,cols-1,board);             }            for(int j=1;j<cols-1;j++)          {              dfs(0,j,board);                dfs(rows-1,j,board);           }                        for(int i=0;i<rows;i++)                for(int j=0;j<cols;j++)                {                    if(board[i][j]=='O')                        board[i][j]='X';                  if(board[i][j]=='#')                        board[i][j]='O';                     }            return;              }    }; 


这样就可以完全的 Juge Large 了。 

思路三:广度优先BFS

class Solution {private:    struct Node    {        int x,y;        Node(){};        Node(int a,int b):x(a),y(b){};    };public:    void solve(vector<vector<char>> &board) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        int rows = board.size();        if(rows<=2) return ;        int cols = board[0].size();        queue<Node> myqueue;        for(int i=0;i<rows;i++)        {            if(board[i][0]=='O')            {                board[i][0]='#';                myqueue.push(Node(i,0));            }            if(board[i][rows-1]=='O')            {                board[i][rows-1]='#';                myqueue.push(Node(i,rows-1));            }                    }                for(int j=1;j<cols-1;j++)        {            if(board[0][j]=='O')            {                board[0][j]='#';                myqueue.push(Node(0,j));            }            if(board[cols-1][j]=='O')            {                board[cols-1][j]='#';                myqueue.push(Node(cols-1,j));            }                    }                const int Direct[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};                while(!myqueue.empty())        {            Node mynode = myqueue.front();            myqueue.pop();            for(int i=0;i<4;i++)            {                int tx = mynode.x+Direct[i][0];                int ty = mynode.y+Direct[i][1];                if(tx<0 || tx>=board.size() || ty<0 || ty>=board[0].size() || board[tx][ty]!='O')                    continue ;                board[tx][ty]='#';                myqueue.push(Node(tx,ty));            }                    }                for(int i=0;i<rows;i++)            for(int j=0;j<cols;j++)            {                if(board[i][j]=='O')                    board[i][j]='X';                if(board[i][j]=='#')                    board[i][j]='O';            }                  }};


当然可以不用建立 Node 结构体,而是  queue<pair<int, int>> Q;      Q.push(make_pair(i , j)); 来实现。

速度更快。


最新版本:

public class Solution {        // use a queue to do BFSprivate Queue<Integer> queue = new LinkedList<Integer>();        public void solve(char[][] board) {        if(board == null){            return;        }        int row = board.length;        if(row <= 2) {            return;        }        int col = board[0].length;        if(col <= 2){            return;        }                for(int i=0; i<row; i++){            if(board[i][0] == 'O'){                bfs(i, 0, board);            }            if(board[i][col-1] == 'O'){                bfs(i, col-1, board);            }        }                for(int j=0; j<col-1; j++){            if(board[0][j] == 'O'){                bfs(0, j, board);            }            if(board[row-1][j] == 'O'){                bfs(row-1, j, board);            }        }        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] == '#'){                    board[i][j] = 'O';                }            }        }            }        private void bfs(int i, int j, char[][] board) {        int row = board.length;        int col = board[0].length;        fillCell(i, j, board);                while(!queue.isEmpty()){            int cur = queue.poll();            int m = cur/col;            int n = cur%col;            fillCell(m+1, n, board);            fillCell(m-1, n, board);            fillCell(m, n+1, board);            fillCell(m, n-1, board);        }    }        private void fillCell(int i, int j, char[][] board){        int row = board.length;        int col = board[0].length;        if(i < 0 || i >= row || j < 0 || j>=col){            return;        }        if(board[i][j] == 'O'){            board[i][j] = '#';            queue.offer(i*col+j);        }    }            // DFS: Line 50: java.lang.StackOverflowError    private void dfs(int i, int j, char[][] board) {        int row = board.length;        int col = board[0].length;        if(i < 0 || i >= row || j < 0 || j>=col){            return;        }        if(board[i][j] == 'O'){            board[i][j] = '#';            dfs(i+1, j, board);            dfs(i-1, j, board);            dfs(i, j+1, board);            dfs(i, j-1, board);        }            }    }

 



原创粉丝点击