代码随想录算法训练营第五十一天|图论part2

99.岛屿数量****深搜

题目链接:99. 岛屿数量

文章讲解:代码随想录

思路:

先将岛屿数据存储到二维矩阵,遍历二维矩阵,遇到1,则统计数量+1,然后将该岛屿四个方向的岛屿都标为已访问。

记得处理边界情况

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void dfs(vector<vector<int>>graph,vector<vector<bool>>&isvisited,int x,int y){
    for(int i=0;i<4;i++){//考虑四个方向
        int nextx=x+dir[i][0];
        int nexty=y+dir[i][1];
        //边界检查
        if(nextx<1||nextx>=graph.size()||nexty<1||nexty>=graph[0].size())continue;
        if(graph[nextx][nexty]==1&&!isvisited[nextx][nexty]){
            isvisited[nextx][nexty]=true;
            dfs(graph,isvisited,nextx,nexty);
        }
    }  
}

int main(){
    int n,m,x;
    cin>>n>>m;
    vector<vector<int>>graph(n+1,vector<int>(m+1,1));
    vector<vector<bool>>isvisited(n+1,vector<bool>(m+1,false));
    for(int i=1;i<=n;i++){                  //用二维矩阵存储图
        for(int j=1;j<=m;j++){
            cin>>x;
            graph[i][j]=x;
        }
    }

    int result=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(!isvisited[i][j]&&graph[i][j]){
                isvisited[i][j]=true;
                result++;
                dfs(graph,isvisited,i,j);  //将相连的陆地标记为已访问
            }
        }
    }
    cout<<result<<endl;
}

99.岛屿数量****广搜

题目链接:99. 岛屿数量

文章讲解:代码随想录

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void bfs(vector<vector<int>>graph,vector<vector<bool>>&isvisited,int x,int y){
    queue<pair<int,int>>mq;
    mq.push({x,y});    //注意pair的用法
    while(!mq.empty()){
        auto current = mq.front();  // ✅ 取出当前节点!!!!!!!!!!
        mq.pop();
        int curx = current.first;
        int cury = current.second;
        for(int i=0;i<4;i++){//考虑四个方向
            int nextx=curx+dir[i][0];
            int nexty=cury+dir[i][1];
            if(nextx<1||nextx>=graph.size()||nexty<1||nexty>=graph[0].size())continue;
            if(graph[nextx][nexty]==1&&!isvisited[nextx][nexty]){
                isvisited[nextx][nexty]=true;
                mq.push({nextx,nexty});
            }
        }
    }

}

int main(){
    int n,m,x;
    cin>>n>>m;
    vector<vector<int>>graph(n+1,vector<int>(m+1,1));
    vector<vector<bool>>isvisited(n+1,vector<bool>(m+1,false));
    for(int i=1;i<=n;i++){                  //用二维矩阵存储图
        for(int j=1;j<=m;j++){
            cin>>x;
            graph[i][j]=x;
        }
    }

    int result=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(!isvisited[i][j]&&graph[i][j]){
                isvisited[i][j]=true;
                result++;
                bfs(graph,isvisited,i,j);  //将相连的陆地标记为已访问
            }
        }
    }
    cout<<result<<endl;
}

广度优先搜索遍历:

新建一个队列,当前节点入队,

while队列不为空,获取队首节点,处理当前节点逻辑,符合条件的入队。

100.岛屿的最大面积

题目链接:100. 岛屿的最大面积

文章讲解:代码随想录

思路:

基本解法与上题一样

找到一个岛屿 然后用广度或者深度优先搜索去遍历周围相连的岛屿,每有一个相连,面积加1

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
//深度优先
void dfs(vector<vector<int>>graph,vector<vector<bool>>&visited,int &area,int x, int y){
    for(int i=0;i<4;i++){
        int nextx=x+dir[i][0];
        int nexty=y+dir[i][1];
        if(nextx<0||nextx>=graph.size()||nexty<0||nexty>graph[0].size()) continue;
        if(graph[nextx][nexty]==1&&!visited[nextx][nexty]){
            visited[nextx][nexty]=true;
            area++;
            dfs(graph,visited,area,nextx,nexty);
        }
    }
}
//广度优先
void bfs(vector<vector<int>>graph,vector<vector<bool>>&visited,int &area,int x, int y){
    queue<pair<int,int>>mq;    
    mq.push({x,y});                //当前节点入队
    while(!mq.empty()){
        auto curnode=mq.front();   //队首节点出队
        mq.pop();
        int curx=curnode.first;
        int cury=curnode.second;
        for(int i=0;i<4;i++){     //处理当前节点有联系的
            int nextx=curx+dir[i][0];
            int nexty=cury+dir[i][1];
            if(nextx<0||nextx>=graph.size()||nexty<0||nexty>graph[0].size()) continue;
            if(graph[nextx][nexty]==1&&!visited[nextx][nexty]){
                visited[nextx][nexty]=true;
                area++;
            mq.push({nextx,nexty});  //有联系的入队
        }
    }
    }
}

int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>>graph(n+1,vector<int>(m+1,0));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>graph[i][j];
        }
    }
    vector<vector<bool>>visited(n+1,vector<bool>(m+1,false));
    int maxArea=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(graph[i][j]==1&&!visited[i][j]){
                int area=1;
                visited[i][j]=true;
                bfs(graph,visited,area,i,j);
                // dfs(graph,visited,area,i,j);
                maxArea=max(maxArea,area);
            }
        }
    }
    cout<<maxArea<<endl;
}
相关推荐
程序员东岸2 小时前
《数据结构——排序(中)》选择与交换的艺术:从直接选择到堆排序的性能跃迁
数据结构·笔记·算法·leetcode·排序算法
程序员-King.2 小时前
day104—对向双指针—接雨水(LeetCode-42)
算法·贪心算法
神仙别闹3 小时前
基于C++实现(控制台)应用递推法完成经典型算法的应用
开发语言·c++·算法
Ayanami_Reii3 小时前
进阶数据结构应用-一个简单的整数问题2(线段树解法)
数据结构·算法·线段树·延迟标记
listhi5203 小时前
基于改进SET的时频分析MATLAB实现
开发语言·算法·matlab
Keep_Trying_Go4 小时前
基于Zero-Shot的目标计数算法详解(Open-world Text-specified Object Counting)
人工智能·pytorch·python·算法·多模态·目标统计
xl.liu4 小时前
零售行业仓库商品数据标记
算法·零售
confiself4 小时前
通义灵码分析ms-swift框架中CHORD算法实现
开发语言·算法·swift
做怪小疯子4 小时前
LeetCode 热题 100——二叉树——二叉树的层序遍历&将有序数组转换为二叉搜索树
算法·leetcode·职场和发展
CoderYanger5 小时前
递归、搜索与回溯-记忆化搜索:38.最长递增子序列
java·算法·leetcode·1024程序员节