[leetcode/lintcode 题解] 谷歌面试题:找出有向图中的弱连通分量
请找出有向图中弱连通分量。图中的每个节点包含 1 个标签和1 个相邻节点列表。(有向图的弱连通分量是任意两点均有有向边相连的极大子图)
将连通分量内的元素升序排列。
图模型说明:
Graph
For example:
{1,2,4#2,1,4#3,5#4,1,2#5,3} represents follow graph:
------
\ | |
\ | |
\ | |
\ | |
we use # to split each node information.
1,2,4 represents that 2, 4 are 1's neighbors
2,1,4 represents that 1, 4 are 2's neighbors
3,5 represents that 5 is 3's neighbor
4,1,2 represents that 1, 2 are 4's neighbors
5,3 represents that 3 is 5's neighbor
样例 1:
输入: {,,#,#,###,}
输出: [[,,],[,,]]
解释:
-----> -->
\ | ^
\ | |
\ |
\ v
->
样例 2:
输入: {,#,#,}
输出: [[,,]]
【题解】
算法:并查集
并查集是一种可以动态维护若干个不重叠的集合,并支持合并与查询两种操作的一种数据结构
一般我们建立一个数组fa或者用map表示一个并查集,fa[i]表示i的父节点。
- 初始化:每一个点都是一个集合,因此自己的父节点就是自己fa[i]=i
- 查询:每一个节点不断寻找自己的父节点,若此时自己的父节点就是自己,那么该点为集合的根结点,返回该点。
- 修改:合并两个集合只需要合并两个集合的根结点,即fa[RootA]=RootB,其中RootA,RootB是两个元素的根结点。
- 路径压缩:实际上,我们在查询过程中只关心根结点是什么,并不关心这棵树的形态(有一些题除外)。因此我们可以在查询操作的时候将访问过的每个点都指向树根,这样的方法叫做路径压缩,单次操作复杂度为O(logn),经过路径压缩后可将查询时间优化到O(1)
我们用um作为father数组维护点之间的关系,通过并查集连通块,将有向连接转换为无向连接
思路
对于图上上两个点,只要他们有连边关系,那么他们就属于同一个弱连通分量
于是这道题我们就可以转换为无向图找联通块
算法流程
- 遍历图上节点,对于有连边关系的两个点,通过并查集将他们合并为一个合集
- 遍历并查集中的每一个点,找到其父亲,再加入父亲所在的 List 中
- 将所有 List 按照点从小到大排序输出
复杂度分析
- 时间复杂度
O(n) - 并查集的复杂度
- 空间复杂度
O(n) - 需要用一个map去记录点与点之间的关系
public class Solution {
/*
* @param nodes: a array of Directed graph node
* @return: a connected set of a directed graph
*/
private Map<Integer, Integer> um=null;
public List<List<Integer>> connectedSet2(ArrayList<DirectedGraphNode> nodes) {
um = new HashMap<>();
for (DirectedGraphNode node : nodes) {//将所有连通点用并查集建立图
find(node.label);
for (DirectedGraphNode neighbor : node.neighbors) {
connect(node.label, neighbor.label);
}
}
Map<Integer, List<Integer>> hash = new HashMap<>();
for (Integer roots : um.keySet()) {//查找每个节点所属的块
int father = find(roots);
if (!hash.containsKey(father)) {
hash.put(father, new ArrayList<>());
}
List<Integer> list = hash.get(father);
list.add(roots);
Collections.sort(list);
}
return new ArrayList<>(hash.values());
}
private int find (int x) {//查询函数
if (!um.containsKey(x)) {
um.put(x,x);
}
int father = um.get(x);
if (father == x) {
return x;
}
father = find(father);
um.put(x, father);
return father;
}
private void connect(int a, int b) {//合并函数
int roota = find(a),rootb=find(b);
if (roota != rootb) {
um.put(Math.min(roota, rootb), Math.max(roota, rootb));
}
}
}
[leetcode/lintcode 题解] 谷歌面试题:找出有向图中的弱连通分量的更多相关文章
- [leetcode/lintcode 题解] 微软面试题:股票价格跨度
编写一个 StockSpanner 类,它收集某些股票的每日报价,并返回该股票当日价格的跨度. 今天股票价格的跨度被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今天). 例如 ...
- [leetcode/lintcode 题解] Amazon面试题:连接棒材的最低费用
为了装修新房,你需要加工一些长度为正整数的棒材 sticks. 如果要将长度分别为 X 和 Y 的两根棒材连接在一起,你需要支付 X + Y 的费用. 由于施工需要,你必须将所有棒材连接成一根. 返回 ...
- [leetcode/lintcode 题解] Google面试题:合法组合
给一个单词s,和一个字符串集合str.这个单词每次去掉一个字母,直到剩下最后一个字母.求验证是否存在一种删除的顺序,这个顺序下所有的单词都在str中.例如单词是’abc’,字符串集合是{‘a’,’ab ...
- [leetcode/lintcode 题解] 微软面试题:公平索引
现在给你两个长度均为N的整数数组 A 和 B. 当(A[0]+...A[K-1]),(A[K]+...+A[N-1]),(B[0]+...+B[K-1]) 和 (B[K]+...+B[N-1])四个和 ...
- [leetcode/lintcode 题解] 微软 面试题:实现 Trie(前缀树)
实现一个 Trie,包含 insert, search, 和 startsWith 这三个方法. 在线评测地址:领扣题库官网 样例 1: 输入: insert(" ...
- Tree Operations 打印出有向图中的环
题目: You are given a binary tree with unique integer values on each node. However, the child pointers ...
- leetcode & lintcode 题解
刷题备忘录,for bug-free 招行面试题--求无序数组最长连续序列的长度,这里连续指的是值连续--间隔为1,并不是数值的位置连续 问题: 给出一个未排序的整数数组,找出最长的连续元素序列的长度 ...
- [LeetCode] Find All Numbers Disappeared in an Array 找出数组中所有消失的数字
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...
- 一起来刷《剑指Offer》-- 题目一:找出数组中重复的数字(Python多种方法实现)
数组中重复的数字 最近在复习算法和数据结构(基于Python实现),然后看了Python的各种"序列"--比如列表List.元组Tuple和字符串String,后期会写一篇博客介绍 ...
随机推荐
- Java内置定时器Timer
Timer是Java内置的一个定时任务,类似于JavaScript里面的setTimeout()和setInterval()方法,可以延迟一定的时间执行任务,也可以按时间间隔重复执行任务. Timer ...
- 洛谷 CF1012C Hills (动态规划)
题目大意:有n个山丘 , 可以在山丘上建房子 , 建房子的要求是 : 该山丘的左右山丘严格的矮于该山丘 (如果有的话),你有一架挖掘机,每单位时间可以给一个山丘挖一个单位的高度,问你想要建造 1,2, ...
- 推荐一种通过刷leetcode来增强技术功底的方法
背景 如果前人认为这个一种学习提高或者检验能力的成功实践.而自己目前又没有更好的方法,那就不妨试一试. 而不管作为面试官还是被面试者,编码题最近越来越流行.而两种角色都需要思考的问题是希望考察什么能力 ...
- int与bigdecimal的相互转换
int转bigdecimal BigDecimal number = new BigDecimal(0); int value=score; number=BigDecimal.valueOf((in ...
- P5676 [GZOI2017]小z玩游戏【Tarjan】
小z玩游戏 Tarjan算是板子题吧,但是要稍微做一些修改,建边需要多考虑,建立"虚点". 题目描述 小 z 很无聊. 小 z 要玩游戏. 小 z 有\(N\)个新游戏,第\(i\ ...
- HDU 5969 最大的位或【贪心】
题目 B君和G君聊天的时候想到了如下的问题. 给定自然数l和r ,选取2个整数x,y满足l <= x <= y <= r ,使得x|y最大. 其中|表示按位或,即C. C++. Ja ...
- Python分析最近大火的网剧《隐秘的角落》,看看网友们有什么看法
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 估计最近很火的连续剧<隐秘的角落>大家趁着端午假期都看过了吧? ...
- Sharepoint 2013设置customErrors
原文地址:http://www.cnblogs.com/renzh/archive/2013/03/05/2944309.html#3407239 一.首先设置IIS中的Web.config文件 找到 ...
- Volatile关键字的解读
原子性 定义: 在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,要么不执行. Java内存模型只保证了基本读取和赋值是原子性操作,如果要实现更大范围 ...
- 给大家分享一下less的使用几个技巧
1.层级关系 让这个box范围内的全部包进来,这样的话就完美的进行调节,再也不用到处找第几行第几个,我刚才在哪个位置给覆盖了.一看便知! .box{ width: %; height: 300px; ...