200 / 130 Number of Islands / Surrounded Regions

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

分析:

拖上一題的福,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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章