[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 ithand 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:
- N is in range [1,200].
- M[i][i] = 1 for all students.
- If M[i][j] = 1, then M[j][i] = 1.
这道题让我们求朋友圈的个数,题目中对于朋友圈的定义是可以传递的,比如A和B是好友,B和C是好友,那么即使A和C不是好友,那么他们三人也属于一个朋友圈。那么比较直接的解法就是 DFS 搜索,对于某个人,遍历其好友,然后再遍历其好友的好友,那么就能把属于同一个朋友圈的人都遍历一遍,同时标记出已经遍历过的人,然后累积朋友圈的个数,再去对于没有遍历到的人在找其朋友圈的人,这样就能求出个数。其实这道题的本质是之前那道题 Number of Connected Components in an Undirected Graph,其实许多题目的本质都是一样的,就是看我们有没有一双慧眼能把它们识别出来:
解法一:
class Solution {
public:
int findCircleNum(vector<vector<int>>& M) {
int n = M.size(), res = ;
vector<bool> visited(n, false);
for (int i = ; i < n; ++i) {
if (visited[i]) continue;
helper(M, i, visited);
++res;
}
return res;
}
void helper(vector<vector<int>>& M, int k, vector<bool>& visited) {
visited[k] = true;
for (int i = ; i < M.size(); ++i) {
if (!M[k][i] || visited[i]) continue;
helper(M, i, visited);
}
}
};
我们也可以用 BFS 来遍历朋友圈中的所有人,解题思路和上面大同小异,参见代码如下:
解法二:
class Solution {
public:
int findCircleNum(vector<vector<int>>& M) {
int n = M.size(), res = ;
vector<bool> visited(n, false);
queue<int> q;
for (int i = ; i < n; ++i) {
if (visited[i]) continue;
q.push(i);
while (!q.empty()) {
int t = q.front(); q.pop();
visited[t] = true;
for (int j = ; j < n; ++j) {
if (!M[t][j] || visited[j]) continue;
q.push(j);
}
}
++res;
}
return res;
}
};
下面这种解法叫联合查找 Union Find,也是一种很经典的解题思路,在之前的两道道题 Graph Valid Tree 和 Number of Connected Components in an Undirected Graph 中也有过应用,核心思想是初始时给每一个对象都赋上不同的标签,然后对于属于同一类的对象,在 root 中查找其标签,如果不同,那么将其中一个对象的标签赋值给另一个对象,注意 root 数组中的数字跟数字的坐标是有很大关系的,root 存的是属于同一组的另一个对象的坐标,这样通过 getRoot 函数可以使同一个组的对象返回相同的值,参见代码如下:
解法三:
class Solution {
public:
int findCircleNum(vector<vector<int>>& M) {
int n = M.size(), res = n;
vector<int> root(n);
for (int i = ; i < n; ++i) root[i] = i;
for (int i = ; i < n; ++i) {
for (int j = i + ; j < n; ++j) {
if (M[i][j] == ) {
int p1 = getRoot(root, i);
int p2 = getRoot(root, j);
if (p1 != p2) {
--res;
root[p2] = p1;
}
}
}
}
return res;
}
int getRoot(vector<int>& root, int i) {
while (i != root[i]) {
root[i] = root[root[i]];
i = root[i];
}
return i;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/547
类似题目:
Number of Connected Components in an Undirected Graph
参考资料:
https://leetcode.com/problems/friend-circles/
https://leetcode.com/problems/friend-circles/discuss/101440/c-bfs
https://leetcode.com/problems/friend-circles/discuss/101338/Neat-DFS-java-solution
https://leetcode.com/problems/friend-circles/discuss/101387/Easy-Java-Union-Find-Solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 547. Friend Circles 朋友圈的更多相关文章
- LeetCode 547. Friend Circles 朋友圈(C++/Java)
题目: https://leetcode.com/problems/friend-circles/ There are N students in a class. Some of them are ...
- [LeetCode]547. Friend Circles朋友圈数量--不相邻子图问题
/* 思路就是遍历所有人,对于每一个人,寻找他的好友,找到好友后再找这个好友的好友 ,这样深度优先遍历下去,设置一个flag记录是否已经遍历了这个人. 其实dfs真正有用的是flag这个变量,因为如果 ...
- 547 Friend Circles 朋友圈
班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指所有朋友的集合.给 ...
- [LeetCode] Friend Circles 朋友圈
There are N students in a class. Some of them are friends, while some are not. Their friendship is t ...
- Leetcode547: Friend Circles 朋友圈问题
问题描述 在一个班级里有N个同学, 有些同学是朋友,有些不是.他们之间的友谊是可以传递的比如A和B是朋友,B和C是朋友,那么A和C也是朋友.我们定义 friend circle为由直接或者间接都是朋友 ...
- Leetcode之深度优先搜索(DFS)专题-547. 朋友圈(Friend Circles)
Leetcode之深度优先搜索(DFS)专题-547. 朋友圈(Friend Circles) 深度优先搜索的解题详细介绍,点击 班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递 ...
- Java实现 LeetCode 547 朋友圈(并查集?)
547. 朋友圈 班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指 ...
- [LeetCode]547. 朋友圈(DFS)
题目 班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指所有朋友的集 ...
- LeetCode 547 朋友圈
题目: 班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指所有朋友的 ...
随机推荐
- Appium swipe实现屏幕滑动
在 Appium 中提供 swipe() 方法来模拟用户滑动屏幕. swipe() 实现过程 是先通过在屏幕上标记两个坐标,然后再从开始坐标移动到结束坐标. 先看下 swipe 方法定义: def s ...
- [STL] UVA 10815 安迪的第一个字典 Andy's First Dictionary
1.set 集合 哦....对了,set有自动按照字典序排序功能..... 声明和插入操作 #include <cstdio> #include <vector> #inclu ...
- Autoware 培训笔记 No. 1——构建点云地图
1. 首记 相信许多刚开始玩无人驾驶的人都用过Autoware,对runtime manager都比较熟悉,虽然可以通过各种渠道了解到有些设置,甚至有些设置的app下参数的含义,但是,在真车的使用过程 ...
- kali渗透综合靶机(三)--bulldog2靶机
kali渗透综合靶机(三)--bulldog2靶机 靶机地址:https://download.vulnhub.com/bulldog/Bulldog2.ova 一.主机发现 1.netdiscove ...
- Servlet中实现多个功能案例
如何实现一个Servlet中的多个功能 前言:唉,打脸了,前脚刚说过要跟Servlet正式告别,后脚这不又来了,哈哈,总结出一点东西,纠结了一下还是做个分享吧,学习知识比面子重要,对吧,下回再也不约S ...
- Vertx上传 官网Demo Java版
package io.vertx.example.web.upload; import io.vertx.core.AbstractVerticle; import io.vertx.example. ...
- 如何使用Charles让手机访问PC自定义域名?
需求:移动端访问PC上的自定义域名,如在Nginx上配置的域名 如vv.zzcloud.com这个域名在pc上是通过host映射的方式访问,现在需要在手机上访问到这个域名. 工具:Charles代 ...
- a标使用window.open()方法
<a href="javascript:window.open('../Left_B/L_Gong_gao_Index', 'TencentLogin', 'width=1920px, ...
- 浅谈 Web框架
一.Web框架本质 所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端 二.Web框架功能 socket收发消息 —— wsgiref(测试).uwsgi(线上 ...
- 了解iOS各个版本新特性总结
参考了一下的文章:https://blog.csdn.net/zxtc19920/article/details/54341836 iOS7新特性 · 在iOS7当中,使用麦克风也需要取得用户同意了. ...