算法与数据结构基础 - 合并查找(Union Find)
Union Find算法基础
Union Find算法用于处理集合的合并和查询问题,其定义了两个用于并查集的操作:
- Find: 确定元素属于哪一个子集,或判断两个元素是否属于同一子集
- Union: 将两个子集合并为一个子集
并查集是一种树形的数据结构,其可用数组或unordered_map表示:
Find操作即查找元素的root,当两元素root相同时判定他们属于同一个子集;Union操作即通过修改元素的root(或修改parent)合并子集,下面两个图展示了id[6]由6修改为9的变化:
图片来源 这里
Union Find算法应用
Union Find可用于解决集合相关问题,如判断某元素是否属于集合、两个元素是否属同一集合、求解集合个数等,算法框架如下:
//261. Graph Valid Tree bool validTree(int n, vector<pair<int, int>>& edges) { vector<); for(auto edge:edges){ //find查看两点是否已在同一集合 int x=find(num,edge.first); int y=find(num,edge.second); if(x==y) return false; //两点已在同一集合情况下则出现环 //union让两点加入同一集合 num[x]=y; } ==edges.size(); } int find(vector<int>&num,int i){ ) return i; return find(num,num[i]); //id[id[...id[i]...]] }
一些情况下为清晰和解偶会将Uinon Find实现为一个类,独立出明显的Union和Find两个操作。
相关LeetCode题:
947. Most Stones Removed with Same Row or Column 题解
算法优化
有两种常用的方法用来降低并查集树形结构的高度、以减少Uinon Find算法的时间复杂度,这两种方法是:
Weighting(或称作Ranking): 使用多一个数组记录每个集合的size,Uinon时将size小的集合挂到size大的集合下,例如:
对3、5 Uinon,因3所在集合元素size 4大于5所在集合元素size 2,将6挂到9下而不是将9挂到6下。
Path compression: 对一个集合下的元素直接挂到root之下,而不是挂到其parent,path compression实现很简单只需在Find中加一行代码:
string find(unordered_map<string,string>& root,string s){ if(root[s]!=s) root[s]=find(root,root[s]); return root[s]; }
加入path compression也能实现减少并查集树高度的效果,图示如下:
Weighting和Path compression两种方法可以同时使用,这样使得对N个元素进行M次Union Find操作的时间复杂度可以减少到 (M+N)lgN。因lgN随N的增长变化很小,所以整体算法时间复杂度接近于线性的时间复杂度。
相关LeetCode题:
924. Minimize Malware Spread 题解
算法与数据结构基础 - 合并查找(Union Find)的更多相关文章
- 算法与数据结构基础 - 折半查找(Binary Search)
Binary Search基础 应用于已排序的数据查找其中特定值,是折半查找最常的应用场景.相比线性查找(Linear Search),其时间复杂度减少到O(lgn).算法基本框架如下: //704. ...
- 算法与数据结构基础 - 图(Graph)
图基础 图(Graph)应用广泛,程序中可用邻接表和邻接矩阵表示图.依据不同维度,图可以分为有向图/无向图.有权图/无权图.连通图/非连通图.循环图/非循环图,有向图中的顶点具有入度/出度的概念. 面 ...
- 算法与数据结构基础 - 分治法(Divide and Conquer)
分治法基础 分治法(Divide and Conquer)顾名思义,思想核心是将问题拆分为子问题,对子问题求解.最终合并结果,分治法用伪代码表示如下: function f(input x size ...
- 算法与数据结构基础 - 数组(Array)
数组基础 数组是最基础的数据结构,特点是O(1)时间读取任意下标元素,经常应用于排序(Sort).双指针(Two Pointers).二分查找(Binary Search).动态规划(DP)等算法.顺 ...
- 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority queue)
堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...
- 算法与数据结构基础 - 广度优先搜索(BFS)
BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...
- 算法与数据结构基础 - 哈希表(Hash Table)
Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...
- 算法与数据结构基础 - 二叉树(Binary Tree)
二叉树基础 满足这样性质的树称为二叉树:空树或节点最多有两个子树,称为左子树.右子树, 左右子树节点同样最多有两个子树. 二叉树是递归定义的,因而常用递归/DFS的思想处理二叉树相关问题,例如Leet ...
- 算法与数据结构基础 - 双指针(Two Pointers)
双指针基础 双指针(Two Pointers)是面对数组.链表结构的一种处理技巧.这里“指针”是泛指,不但包括通常意义上的指针,还包括索引.迭代器等可用于遍历的游标. 同方向指针 设定两个指针.从头往 ...
随机推荐
- Codeforces 758D:Ability To Convert(思维+模拟)
http://codeforces.com/problemset/problem/758/D 题意:给出一个进制数n,还有一个数k表示在n进制下的值,求将这个数转为十进制最小可以是多少. 思路:模拟着 ...
- 2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D:Distribution in Metagonia(构造)
http://codeforces.com/gym/100801/attachments 题意:给出一个数n(1 <= n <= 1e18),将 n 拆成 m 个整数,其中 m 必须是 2 ...
- Hackbar再次更新后的破解思路 v2.2.6
不得不说在日常测试和渗透测试中hackbar这一插件给我带来了很大的便利 Hackbar在2.1.3之后的版本就开始收费了虽说价格不是很贵,但我们还是本着学习研究的心态来看看怎么绕过收费验证. 谷歌: ...
- os.path.join用法
os.path.join()函数:连接两个或更多的路径名组件 1.如果各组件名首字母不包含’/’,则函数会自动加上 2.如果有一个组件是一个绝对路径,则在它之前的所有组件均会被舍弃 3.如果最后一个组 ...
- 探究Hybrid-APP技术原理
探究Hybrid-APP技术原理 author: @TiffanysBear 背景 随着Web技术的发展和移动互联网的发展,Hybrid技术已经成为一种前端开发的主流技术方案.那什么是Hybrid A ...
- Java面试题必备知识之ThreadLocal
老套路,先列举下关于ThreadLocal常见的疑问,希望可以通过这篇学习笔记来解决这几个问题: ThreadLocal是用来解决什么问题的? 如何使用ThreadLocal? ThreadLocal ...
- Spring_简单入门(学习笔记1)
Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架. 具体介绍参考 一:IoC(Inversion of Control)控制反转,将创建对象实例反转给spri ...
- 【Arduino】66种传感器系列实验(1)---干簧管传感器模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和各种模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里 ...
- Linux 下实践 VxLAN:虚拟机和 Docker 场景
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,欢迎大家关注,二维码文末可以扫. 在上篇文章 ...
- 图解Redis之数据结构篇——整数集合
前言 整数集合(intset)并不是一个基础的数据结构,而是Redis自己设计的一种存储结构,是集合键的底层实现之一,当一个集合只包含整数值元素,并且这个集合的元素数量不多时, Redis i ...