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;
    }
};
相关推荐
zh路西法5 小时前
【10天速通ROS2-PX4无人机】(四) 关掉GPS和气压计,纯激光定位还能飞吗
c++·无人机·px4·ros2·卡尔曼滤波·fastlio2
稚南城才子,乌衣巷风流5 小时前
支配树(Dominator Tree)详解:概念、算法与应用
算法
稚南城才子,乌衣巷风流6 小时前
动态开点:原理、实现与应用场景
数据结构·算法
yyds_yyd_100866 小时前
1464. 数组中两元素的最大乘积(2026.07.27)
数据结构·c++·算法·leetcode
KaMeidebaby7 小时前
卡梅德生物技术快报 | 核酸适配体文库测序:核酸适配体文库测序的技术原理、实验流程与数据解析
前端·网络·数据库·人工智能·算法
geovindu8 小时前
CSharp: Breadth First Search Algorithm and Depth First Search Algorithm
开发语言·后端·算法·c#·.net·搜索算法
库克克8 小时前
【C++】set 与multiset
开发语言·c++
网络安全零基础教程8 小时前
网络安全春招面试避坑与复盘指南
linux·网络·安全·web安全·面试·职场和发展
Mortalbreeze9 小时前
深入 Linux Socket 编程:端口号、网络字节序与 struct sockaddr 详解
linux·服务器·网络·c++
ekkoalex9 小时前
训练框架以及算法实现的框架
算法