当前位置: 首页 > news >正文

547.力扣LeetCode_ 省份数量

目录

方法1:并查集

直接统计结果

间接统计结果

两种统计方法对比

方法2:dfs 深度优先

邻接矩阵转链式邻接表

dfs核心代码

dfs主函数

方法3:bfs广度优先

bfs核心代码

bfs主函数

DFS与BFS对比

核心差异

主函数调用差异

访问节点的时机



  • 方法1:并查集

  • 直接统计结果

#define MaxSize 200
int parent[MaxSize],rank[MaxSize];void Initialize(int n){for(int i=0;i<n;i++){parent[i]=i;rank[i]=1;}
}int find(int x){if(parent[x]!=x){parent[x]=find(parent[x]);}return parent[x];
}void Union(int x,int y){int x_root=find(x);int y_root=find(y);if(x_root!=y_root){if(rank[x_root]>rank[y_root]){parent[y_root]=x_root;}else if(rank[x_root]<rank[y_root]){parent[x_root]=y_root;}else{parent[y_root]=x_root;rank[x_root]++;}}
}int findCircleNum(int** isConnected, int isConnectedSize, int* isConnectedColSize) {int n=isConnectedSize;Initialize(n);for(int i=0;i<n;i++){for(int j=i+1;j<n;j++){if(isConnected[i][j]){Union(i,j);}}}int count=0;for(int i=0;i<n;i++){if(parent[i]==i) count++;}return count;
}

  • 间接统计结果

int findCircleNum(int** isConnected, int isConnectedSize, int* isConnectedColSize) {int n=isConnectedSize;Initialize(n);int count=0;for(int i=0;i<n;i++){for(int j=i+1;j<n;j++){if(isConnected[i][j]){if(find(i)!=find(j)){Union(i,j);count++;}}}}return n-count;
}

  • 两种统计方法对比

直接统计法

核心逻辑:通过遍历所有节点,统计根节点( parent[i] == i )的数量,以此直接得到连通分量的个数。

间接统计法

核心逻辑:通过计算有效合并的次数来反推连通分量个数。初始时为  n  个分量,每发生一次有效合并,分量数减 1,最终结果为  n - count 。

为何间接统计法必须增加判断

该方法的正确性依赖于计数器  count  的精确性,它必须严格等于有效合并的次数。若缺少 if(find(i) != find(j)) 判断,则每次遇到边 (i,j) 都会执行 count++ ,即使  i  和  j  已连通。如果原图中存在环,会导致count重复计数,最终结果  n - count  偏小。


  • 方法2:dfs 深度优先

  • 邻接矩阵转链式邻接表

typedef struct LinkNode{int data;struct LinkNode* next;
}LinkNode;LinkNode** Get_Adj(int** isConnected,int n){LinkNode **adj=(LinkNode **)calloc(n,sizeof(LinkNode*));int adjColSize[n];memset(adjColSize,0,n*sizeof(int));for(int i=0;i<n;i++){for(int j=i+1;j<n;j++){if(isConnected[i][j]){LinkNode *new_i=(LinkNode *)malloc(sizeof(LinkNode));new_i->data=j;new_i->next=adj[i];adj[i]=new_i;LinkNode *new_j=(LinkNode *)malloc(sizeof(LinkNode));new_j->data=i;new_j->next=adj[j];adj[j]=new_j;                }}}return adj;
}

  • dfs核心代码

void dfs(int cur,LinkNode** adj,bool visited[]){if(visited[cur]) return;visited[cur]=true;LinkNode* p=adj[cur];while(p){int cur_neighbor=p->data;if(!visited[cur_neighbor]){dfs(cur_neighbor,adj,visited);}p=p->next;}
}

  • dfs主函数

int findCircleNum(int** isConnected, int isConnectedSize, int* isConnectedColSize) {int n=isConnectedSize;LinkNode **adj=Get_Adj(isConnected,n);bool visited[n];memset(visited,false,n*sizeof(bool));int count=0;for(int i=0;i<n;i++){if(!visited[i]){count++;dfs(i,adj,visited);}}return count;
}

  • 方法3:bfs广度优先

  • bfs核心代码

void bfs(int cur,LinkNode** adj,bool visited[],int n){int queue[n],front=0,rear=0;queue[rear++]=cur;visited[cur]=true;while(front!=rear){int x=queue[front++];LinkNode *p=adj[x];while(p){int x_neighbor=p->data;if(!visited[x_neighbor]){queue[rear++]=x_neighbor;visited[x_neighbor]=true;}p=p->next;}}
}

  • bfs主函数

int findCircleNum(int** isConnected, int isConnectedSize, int* isConnectedColSize) {int n=isConnectedSize;LinkNode **adj=Get_Adj(isConnected,n);bool visited[n];memset(visited,false,n*sizeof(bool));int count=0;for(int i=0;i<n;i++){if(!visited[i]){count++;bfs(i,adj,visited,n);}}return count;
}

  • DFS与BFS对比

  • 核心差异

DFS 的空间管理依赖于系统的递归调用栈。每次调用  dfs()  函数,系统都会在栈上为其创建一个新的栈帧,用于存储函数参数和局部变量。当函数执行完毕返回时,这个栈帧就会被自动销毁。这种方式的优点是代码简洁,不需要我们手动管理栈结构。缺点是当图的深度很大时,可能会导致栈溢出

BFS 的空间管理则依赖于我们手动维护的队列。我们需要自己创建一个数据结构(数组或链表)来存放所有待访问的节点。代码中传入  n  参数,就是为了在 BFS 函数内部创建一个大小为  n  的数组作为队列。这种方式的优点是避免了递归深度过大导致的栈溢出问题,空间使用更加可控。缺点是需要显式地管理队列的入队和出队操作,代码相对复杂一些。

  • 主函数调用差异

- DFS: dfs(i, adj, visited); 

只需要当前起始节点  i 、邻接表  adj  和访问标记数组  visited 。

递归栈由系统自动管理,不需要知道图的总节点数  n 。

- BFS: bfs(i, adj, visited, n); 

必须多传一个  n  参数。因为函数内部要创建一个能容纳所有节点的队列数组。

  • 访问节点的时机

DFS:在递归函数开始时就标记  visited[cur] = true 。

这确保了节点在被访问之初就被标记,防止被重复处理。

BFS:在节点被加入队列时就立即标记  visited[cur] = true 。

http://www.dtcms.com/a/561315.html

相关文章:

  • Python编程实战—面向对象与进阶语法 | 属性与方法
  • 县级林业网站建设管理河南省住房和城乡建设厅电话
  • 自己怎么做返利网站中国做陶壶的网站有哪些
  • C++11新特性介绍
  • 软考 系统架构设计师系列知识点之杂项集萃(187)
  • 好用百度seo排名优化软件工具(seo快速优化软件)
  • 【SSM框架 | day24 spring IOC 与 DI】
  • .net 8.0 System.InvalidOperationException:“Session has not been configured
  • 网站关键词排名快速提升网站域名空间续费合同
  • 本地大模型、本地embeding、本地数据库、本地RAG Flow搭建方式——从显卡驱动开始
  • 10-神经网络的工作原理:分析神经网络如何学习和推理
  • 无锡做网站的公司网站业务员怎么给客户做方案
  • HarmonyOS Divider组件深度定制:从基础分割到高级视觉表达
  • 外包公司做的网站怎么改密码光辉网络 石家庄网站建设
  • 一道面试高频题:如何判断完全二叉树?
  • 使用Stream API重构你的数据处理
  • ps做网站首页怎么广州公共资源交易
  • discuz 门户网站模板物联网今天正式开网
  • python数据分析学习路线及生态
  • 【Unity踩坑】Unity测试用例命名空间错误解决方案
  • 美日股票数据API对接实战指南
  • 【Android FrameWork】第二天:认识Skia
  • 用dw做网站首页视觉营销网站建设规划分析
  • Spring Security安全框架原理与实战
  • 不用js可以做网站吗黄页88
  • 配置镜像仓库镜像(Registry Mirror)的指南
  • 25套科技商务风PPT模板合集,多场景适配专业演示(PPTX格式)
  • 网站内容收费专业网站定制报价
  • 跟der包学习java_day5「数组(Array)」
  • lerobot框架部署act模型