【启发】leetcode -- 547. Friend Circles【并查集 + 集合标识更新的时机】

2024-03-29 06:18

本文主要是介绍【启发】leetcode -- 547. Friend Circles【并查集 + 集合标识更新的时机】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

Example 1:

Input: 
[[1,1,0],[1,1,0],[0,0,1]]
Output: 2
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. 
The 2nd student himself is in a friend circle. So return 2.

Example 2:

Input: 
[[1,1,0],[1,1,1],[0,1,1]]
Output: 1
Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, 
so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.

Note:

  1. N is in range [1,200].
  2. M[i][i] = 1 for all students.
  3. If M[i][j] = 1, then M[j][i] = 1.

题意概述

给定一个矩阵N*N ,表示N个人之间的朋友关系。朋友关系具有传递性,试找出这N个人中有多少个朋友团体。

分析及解答

解法1:(简明、清晰)
  • 未进行路径压缩
  • 参考:(https://discuss.leetcode.com/topic/85039/java-solution-union-find)
   public int findCircleNum(int[][] M) {int m = M.length, cnt = 0;int[] root = new int[m]; for (int i = 0; i < m; i++) root[i] = i; for (int i = 0; i < m; i++) for (int j = i + 1; j < m; j++)if (M[i][j] == 1) unionFind(root, i, j);for (int i = 0; i < m; i++)if (i == root[i]) cnt++;return cnt;}void unionFind (int[] root, int v1, int v2) {while (root[v1] != v1) v1 = root[v1]; //find v1's rootwhile (root[v2] != v2) v2 = root[v2]; //find v2's rootif (root[v1] != root[v2]) root[v2] = v1; //unite the 2 subtrees }



解法2:(我的丑的版本
  • 注意:发现新的朋友关系之后的影响】当在遍历过程中发现新的朋友关系时,我们不仅仅需要考虑其对于当下正在处理的朋友关系的影响,同时还要考虑对于过去已经建立的朋友关系的影响(可能会连接起以前独立的两个朋友团体)。(易忽略

class Solution {public static int findCircleNum(int[][] M) {if(M == null || M.length == 0){return 0;}int[] friends =  new int[M.length];for(int i = 0; i < friends.length;i++){friends[i] = -1; // -1 表示尚未分配集合。}for(int i = 0; i < M.length; i++){for(int j = i ; j < M.length;j++){//【关键】初始化 朋友关系。(注意遍历次序:自上而下,自左向右)(一个集合中最小的数作为集合的标志)//只有发现存在朋友关系时,才进行相应的处理。if(M[i][j] == 1){//若之前并未分配集合,首次分配集合。if(friends[j] == -1){friends[j] = i;}else{//若j之前已经分配了集合。则需要进一步传递这种朋友关系。int newRoot = find(friends, j);//因为i中可能有自己的集合标志。而与 j的朋友关系,将这两个集合关联了起来,形成一个集合。所以,//我们将其中一个集合的根标记为另一个集合的根。friends[friends[i]] = newRoot;//将i的根标记为新的集合的根。friends[i] = newRoot;}}}}int result = 0;for(int i = 0; i < friends.length; i++){//每个 i = friends[i]的人,都代表着一个朋友团体。if(i == friends[i]){result ++;}}return result;}public static int find(int[] friends,int i){//查找 i 所属于的集合的根(集合的标志)。while(i != friends[i]){i = friends[i];}return i;}
}


这篇关于【启发】leetcode -- 547. Friend Circles【并查集 + 集合标识更新的时机】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/857831

相关文章

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

Oracle 通过 ROWID 批量更新表的方法

《Oracle通过ROWID批量更新表的方法》在Oracle数据库中,使用ROWID进行批量更新是一种高效的更新方法,因为它直接定位到物理行位置,避免了通过索引查找的开销,下面给大家介绍Orac... 目录oracle 通过 ROWID 批量更新表ROWID 基本概念性能优化建议性能UoTrFPH优化建议注

Redis中6种缓存更新策略详解

《Redis中6种缓存更新策略详解》Redis作为一款高性能的内存数据库,已经成为缓存层的首选解决方案,然而,使用缓存时最大的挑战在于保证缓存数据与底层数据源的一致性,本文将介绍Redis中6种缓存更... 目录引言策略一:Cache-Aside(旁路缓存)策略工作原理代码示例优缺点分析适用场景策略二:Re

Pandas利用主表更新子表指定列小技巧

《Pandas利用主表更新子表指定列小技巧》本文主要介绍了Pandas利用主表更新子表指定列小技巧,通过创建主表和子表的DataFrame对象,并使用映射字典进行数据关联和更新,实现了从主表到子表的同... 目录一、前言二、基本案例1. 创建主表数据2. 创建映射字典3. 创建子表数据4. 更新子表的 zb

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

SpringBoot项目使用MDC给日志增加唯一标识的实现步骤

《SpringBoot项目使用MDC给日志增加唯一标识的实现步骤》本文介绍了如何在SpringBoot项目中使用MDC(MappedDiagnosticContext)为日志增加唯一标识,以便于日... 目录【Java】SpringBoot项目使用MDC给日志增加唯一标识,方便日志追踪1.日志效果2.实现步

一文详解SQL Server如何跟踪自动统计信息更新

《一文详解SQLServer如何跟踪自动统计信息更新》SQLServer数据库中,我们都清楚统计信息对于优化器来说非常重要,所以本文就来和大家简单聊一聊SQLServer如何跟踪自动统计信息更新吧... SQL Server数据库中,我们都清楚统计信息对于优化器来说非常重要。一般情况下,我们会开启"自动更新

Python容器类型之列表/字典/元组/集合方式

《Python容器类型之列表/字典/元组/集合方式》:本文主要介绍Python容器类型之列表/字典/元组/集合方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 列表(List) - 有序可变序列1.1 基本特性1.2 核心操作1.3 应用场景2. 字典(D

Java集合中的List超详细讲解

《Java集合中的List超详细讲解》本文详细介绍了Java集合框架中的List接口,包括其在集合中的位置、继承体系、常用操作和代码示例,以及不同实现类(如ArrayList、LinkedList和V... 目录一,List的继承体系二,List的常用操作及代码示例1,创建List实例2,增加元素3,访问元