1.19 力扣中等图论

200. 岛屿数量

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:

复制代码
输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1

示例 2:

复制代码
输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3

思路1:

使用DFS深度搜索,在外层用for循环遍历每个元素,一旦元素为'1'则进入"新岛屿",并在该个"新岛屿"做DFS深度搜索,将周围为"1"的都标记成"已经选择过"。最后记录进入"新岛屿的次数即可"

cpp 复制代码
class Solution {
public:
    //判断该坐标是否符合
    bool isValid(vector<vector<char>>& grid,int row,int col)
    {
        if(row<0||col<0||row>=grid.size()||col>=grid[0].size()) return false;
        return true;
    }
    //dfs将一个岛屿都标记为"已经选择过"
    void dfs(vector<vector<char>>& grid,vector<vector<bool>>& valid,int row,int col)
    {
        if(!isValid(grid,row,col)||!valid[row][col]||grid[row][col]=='0') return;
        valid[row][col]=false;
        //对四个方向进行延深
        if(isValid(grid,row+1,col)) dfs(grid,valid,row+1,col);
        if(isValid(grid,row,col+1)) dfs(grid,valid,row,col+1);
        if(isValid(grid,row-1,col)) dfs(grid,valid,row-1,col);
        if(isValid(grid,row,col-1)) dfs(grid,valid,row,col-1);
    }
    int numIslands(vector<vector<char>>& grid) {
        if(grid.size()==0) return 0;
        vector<vector<bool>> valid(grid.size(),vector<bool>(grid[0].size(),true));
        int ret=0;
        for(int i=0;i<grid.size();i++)
        {
            for(int j=0;j<grid[0].size();j++)
            {
                if(grid[i][j]=='0'||!valid[i][j]) continue;
                //dfs进行染色
                dfs(grid,valid,i,j);
                ret++;
            }
        }
        return ret;
    }
};

思路2:

广度搜索:用类似策略,只是用dfs代替了bfs

cpp 复制代码
class Solution {
public:
    //判断该坐标是否符合
    bool isValid(vector<vector<char>>& grid,int row,int col)
    {
        if(row<0||col<0||row>=grid.size()||col>=grid[0].size()) return false;
        return true;
    }
    //bfs将一个岛屿都标记为"已经选择过"
    void bfs(vector<vector<char>>& grid,vector<vector<bool>>& valid,int row,int col)
    {
        queue<pair<int,int>> q;
        q.push(make_pair(row,col));
        while(!q.empty())
        {
            pair<int,int> temp=q.front();
            q.pop();
            int temp_row=temp.first,temp_col=temp.second;
            //染色
            valid[temp_row][temp_col]=false;
            if(isValid(grid,temp_row+1,temp_col)&&valid[temp_row+1][temp_col]&&grid[temp_row+1][temp_col]=='1') q.push(make_pair(temp_row+1,temp_col));
            if(isValid(grid,temp_row,temp_col+1)&&valid[temp_row][temp_col+1]&&grid[temp_row][temp_col+1]=='1') q.push(make_pair(temp_row,temp_col+1));
            if(isValid(grid,temp_row-1,temp_col)&&valid[temp_row-1][temp_col]&&grid[temp_row-1][temp_col]=='1') q.push(make_pair(temp_row-1,temp_col));
            if(isValid(grid,temp_row,temp_col-1)&&valid[temp_row][temp_col-1]&&grid[temp_row][temp_col-1]=='1') q.push(make_pair(temp_row,temp_col-1));
        }

    }
    int numIslands(vector<vector<char>>& grid) {
        if(grid.size()==0) return 0;
        vector<vector<bool>> valid(grid.size(),vector<bool>(grid[0].size(),true));
        int ret=0;
        for(int i=0;i<grid.size();i++)
        {
            for(int j=0;j<grid[0].size();j++)
            {
                if(grid[i][j]=='0'||!valid[i][j]) continue;
                //bfs进行染色
                bfs(grid,valid,i,j);
                ret++;
            }
        }
        return ret;
    }
};

但以上代码会超时。。。代码中是从队列中取出节点再标记,改为将节点加入队列就立即标记

cpp 复制代码
class Solution {
public:
    //判断该坐标是否符合
    bool isValid(vector<vector<char>>& grid,int row,int col)
    {
        if(row<0||col<0||row>=grid.size()||col>=grid[0].size()) return false;
        return true;
    }
    //bfs将一个岛屿都标记为"已经选择过"
    void bfs(vector<vector<char>>& grid,vector<vector<bool>>& valid,int row,int col)
    {
        queue<pair<int,int>> q;
        q.push(make_pair(row,col));
        //染色
        valid[row][col]=false;
        while(!q.empty())
        {
            pair<int,int> temp=q.front();
            q.pop();
            int temp_row=temp.first,temp_col=temp.second;
            if(isValid(grid,temp_row+1,temp_col)&&valid[temp_row+1][temp_col]&&grid[temp_row+1][temp_col]=='1') 
            {
                q.push(make_pair(temp_row+1,temp_col));
                valid[temp_row+1][temp_col]=false;
            }
            if(isValid(grid,temp_row,temp_col+1)&&valid[temp_row][temp_col+1]&&grid[temp_row][temp_col+1]=='1')
            {
                q.push(make_pair(temp_row,temp_col+1));
                valid[temp_row][temp_col+1]=false;
            } 
            if(isValid(grid,temp_row-1,temp_col)&&valid[temp_row-1][temp_col]&&grid[temp_row-1][temp_col]=='1')
            {
                q.push(make_pair(temp_row-1,temp_col));
                valid[temp_row-1][temp_col]=false;
            } 
            if(isValid(grid,temp_row,temp_col-1)&&valid[temp_row][temp_col-1]&&grid[temp_row][temp_col-1]=='1') 
            {
                q.push(make_pair(temp_row,temp_col-1));
                valid[temp_row][temp_col-1]=false;
            }
        }

    }
    int numIslands(vector<vector<char>>& grid) {
        if(grid.size()==0) return 0;
        vector<vector<bool>> valid(grid.size(),vector<bool>(grid[0].size(),true));
        int ret=0;
        for(int i=0;i<grid.size();i++)
        {
            for(int j=0;j<grid[0].size();j++)
            {
                if(grid[i][j]=='0'||!valid[i][j]) continue;
                //bfs进行染色
                bfs(grid,valid,i,j);
                ret++;
            }
        }
        return ret;
    }
};
相关推荐
handler013 小时前
从源码到二进制:深度拆解 Linux 下 C 程序的编译与链接全流程
linux·c语言·开发语言·c++·笔记·学习
t***5444 小时前
如何在Dev-C++中使用Clang编译器
开发语言·c++
Qbw20044 小时前
【Linux】进程地址空间
linux·c++
6Hzlia5 小时前
【Hot 100 刷题计划】 LeetCode 739. 每日温度 | C++ 逆序单调栈
c++·算法·leetcode
良木生香5 小时前
【C++初阶】:STL——String从入门到应用完全指南(1)
c语言·开发语言·数据结构·c++·算法
XWalnut6 小时前
LeetCode刷题 day16
数据结构·算法·leetcode·链表·动态规划
Kurisu_红莉栖6 小时前
c++复习——const,static字
c++
czxyvX7 小时前
1-Qt概述
c++·qt
齐鲁大虾7 小时前
新人编程语言选择指南
javascript·c++·python·c#