<LeetCode OJ> 200 / 130 Number of Islands / Surrounded Regions

来源:互联网 发布:安邦和谐健康 知乎 编辑:程序博客网 时间:2024/06/06 00:00

Total Accepted: 48411 Total Submissions: 171609 Difficulty: Medium

Given a 2d grid map of '1's (land) and '0's (water), 

count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. 

You may assume all four edges of the grid are all surrounded by water.

Example 1:

11110
11010
11000
00000

Answer: 1

Example 2:

11000
11000
00100
00011

Answer: 3


分析:

这是网上流传最广的深度优先解法,确实漂亮,通俗易理解。

class Solution {public:    int numIslands(vector<vector<char>>& grid) {        int result=0;        if(grid.empty() || grid[0].empty())            return result;        int rows=grid.size();        int cols=grid[0].size();        for(int i=0;i<rows;i++)        {            for(int j=0;j<cols;j++)            {                if(grid[i][j]=='1')//如果是岛屿,那么此处一定有一座岛屿。将和他连在一起的岛屿全部置零                {                    dfs(grid,i,j,rows,cols);//深搜,将该位置(i,j)四周的1都置0                    result++;//发现一座岛屿(很多个1形成,dfs后该岛置零),并且该岛屿被全部置零(不影响另外独立的岛屿判断)                }            }        }        return result;    }    void dfs(vector<vector<char>>& grid,int i,int j,int rows,int cols)    {        grid[i][j]='0';        if(i > 0 && grid[i-1][j] == '1')//上边置0            dfs(grid,i-1,j,rows,cols);        if(i < rows-1 && grid[i+1][j] == '1')//下边同理               dfs(grid,i+1,j,rows,cols);        if(j > 0 && grid[i][j-1] == '1')//左边               dfs(grid,i,j-1,rows,cols);            if(j < cols-1 && grid[i][j+1] == '1')//右边               dfs(grid,i,j+1,rows,cols);        }};



学习别人的并查集解决问题,漂亮:

class Solution {public:    int find(vector<int> & parents, int index) {//寻找index位置的最高祖先(也是一个位置)        if(parents[index]==-1)            return index;        return find(parents, parents[index]);    }    void merge(vector<int> & parents, int a, int b){//合并        int parent_a = find(parents, a);        int parent_b = find(parents, b);        if(parent_a!=parent_b){            parents[parent_b]=parent_a;//set the new 's parent to be old one.            total--;        }    }    int numIslands(vector<vector<char>>& grid) {        int rows = grid.size();        if (rows==0) return 0;        int cols = grid[0].size();        vector<int>parents(rows*cols,-1);        total=rows*cols; //随后减少        int waters=0;        for(int i=0;i<rows;i++){            for(int j=0;j<cols;j++){                if(grid[i][j]=='0')                     waters++;                else{                    int index = i*cols+j;                    //我们只需要考虑已经访问过的,并且合并他们                    //只有相邻的两个需要合并,并且他们均为1                    //并且总是往上边和右边合并                    //如果该岛屿是独立的岛屿,他将会被合并成为一个独立的祖先                    if(i>0 && grid[i-1][j]=='1')                        merge(parents, (i-1)*cols+j, index);                    if(j>0 && grid[i][j-1]=='1')                        merge(parents, i*cols+j-1, index);                }            }        }        return total-waters;    }private:    int total;};




Total Accepted: 54885 Total Submissions: 336458 Difficulty: Medium

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

分析:

拖上一题的福,200. Number of Islands,这一题思路比较明显。

以下答案Runtime Error,查了一下网络,应该是栈溢出了!

class Solution {public:    void solve(vector<vector<char>>& board) {        int rows=board.size();        if(rows==0 || rows==1)            return;        int cols=board[0].size();        for(int i=0;i<cols;i++)//第一行            if(board[0][i]=='O')                dfs(board,0,i,rows,cols);        for(int i=0;i<cols;i++)//最后行            if(board[rows-1][i]=='O')                dfs(board,rows-1,i,rows,cols);                          for(int i=0;i<rows;i++)//第一列            if(board[i][0]=='O')                dfs(board,i,0,rows,cols);         for(int i=0;i<rows;i++)//最后列            if(board[i][cols-1]=='O')                dfs(board,i,cols-1,rows,cols);                        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]=='D')                    board[i][j]='O';                }        }    }    void dfs(vector<vector<char>>& board,int i,int j,int rows,int cols)    {        board[i][j]='D';//将其改成D,区别于被包围的O,便于在最后两层循环中区别那些该被改成X        if(i < rows-1 && board[i+1][j] == 'O')//下边                 dfs(board,i+1,j,rows,cols);          if(j < cols-1 && board[i][j+1] == 'O')//右边                 dfs(board,i,j+1,rows,cols);            if(i > 0 && board[i-1][j] == 'O')//上边              dfs(board,i-1,j,rows,cols);         if(j > 0 && board[i][j-1] == 'O')//zuo边              dfs(board,i,j-1,rows,cols);          }};


学习别人的算法:

广度优先算法

/**------------------------------------    *   日期:2015-02-06    *   作者:SJF0115    *   题目: 130.Surrounded Regions    *   网址:https://oj.leetcode.com/problems/surrounded-regions/    *   结果:AC    *   来源:LeetCode    *   博客:    ---------------------------------------**/    #include <iostream>    #include <cstring>    #include <vector>    #include <queue>    #include <algorithm>    using namespace std;    class Solution {    public:        void solve(vector<vector<char> > &board) {            int row = board.size();            if(row == 0){                return;            }//if            int col = board[0].size();            // 都够不成围绕            if(row <= 2 || col <= 2){                return;            }//if            // 行            for(int i = 0;i < col;++i){                // 第一行                BFS(board,row,col,0,i);                // 最后一行                BFS(board,row,col,row-1,i);            }//for            // 列            for(int j = 0;j < row;++j){                // 第一列                BFS(board,row,col,j,0);                // 最后一列                BFS(board,row,col,j,col-1);            }//for            for(int i = 0;i < row;++i){                for(int j = 0;j < col;j++){                    // 不可以从外界走通的o                    if(board[i][j] == 'O'){                        board[i][j] = 'X';                    }//if                    // 可以从外界走通的o                    else if(board[i][j] == '.'){                        board[i][j] = 'O';                    }                }//for            }//for        }    private:        // row 行数 col 列数 x ,y 当前board位置        void BFS(vector<vector<char>> &board,int row,int col,int x,int y){            queue<pair<int,int> > q;            Pass(board,row,col,x,y,q);            while(!q.empty()){                pair<int,int> point = q.front();                q.pop();                x = point.first;                y = point.second;                // left                Pass(board,row,col,x,y+1,q);                // right                Pass(board,row,col,x,y-1,q);                // up                Pass(board,row,col,x-1,y,q);                // down                Pass(board,row,col,x+1,y,q);            }//while        }        // 四边判断是否走通        void Pass(vector<vector<char>> &board,int row,int col,int x,int y,queue<pair<int,int> > &q){            // 边界条件以及遇到o才能走通            if(x < 0 || x >= row || y < 0 || y >= col || board[x][y] != 'O'){                return;            }//if            // 标记可从外界走通的o            board[x][y] = '.';            // 入队列            q.push(make_pair(x,y));        }    };    int main(){        Solution s;        /*vector<vector<char> > board = {            {'X','X','X','X'},            {'X','O','O','X'},            {'X','X','O','X'},            {'X','O','X','X'}        };*/        vector<vector<char> > board = {            {'X','X','X'},            {'X','O','X'},            {'X','X','X'}        };        s.solve(board);        // 输出        for(int i = 0;i < board.size();i++){            for(int j = 0;j < board[i].size();j++){                cout<<board[i][j]<<" ";            }//for            cout<<endl;        }//for        return 0;    }


注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!

原文地址:http://blog.csdn.net/ebowtang/article/details/51636977

原作者博客:http://blog.csdn.net/ebowtang

本博客LeetCode题解索引:http://blog.csdn.net/ebowtang/article/details/50668895

2 0