最长连续序列

题目[128]:链接

解题思路

节点本身的值作为节点的标号,两节点相邻,即允许合并(x, y)的条件为x == y+1

因为数组中可能会出现值为 -1 的节点,因此不能把 root[x] == -1 作为根节点的特征,所以采取 root[x] == x 作为判断是否为根节点的条件。默认较小的节点作为连通分量的根。

此外,使用 map<int, int> counter 记录节点所在连通分量的节点个数(也是merge 的返回值)。

class Solution
{
public:
unordered_map<int, int> counter;
unordered_map<int, int> root;
int longestConsecutive(vector<int> &nums)
{
int len = nums.size();
// use map to discard the duplicate values
for (int x : nums)
root[x] = x, counter[x] = 1;
int result = len == 0 ? 0 : 1;
for (int x : nums)
{
if (root.count(x + 1) == 1)
result = max(result, merge(x, x + 1));
}
return result;
}
int find(int x)
{
return root[x] == x ? x : (root[x] = find(root[x]));
}
int merge(int x, int y)
{
x = find(x);
y = find(y);
if (x != y)
{
root[y] = x;
counter[x] += counter[y];
}
return counter[x];
}
};

连通网络的操作次数

题目[1319]:Link.

解题思路

考虑使用并查集。

考虑到特殊情况,要使 N 个点连通,至少需要 N-1 条边,否则返回 -1 即可。

通过并查集,可以计算出多余的边的数目(多余的边是指使得图成环的边),只要 findroot(x) == findroot(y) 说明边 (x,y) 使得图成环。

遍历所有边,在并查集中执行合并 merge 操作(多余的边忽略不合并,只进行计数)。设 components 为合并后后 root 数组中 -1 的个数(也就是连通分量的个数),要想所有的连通分支都连起来,需要 components - 1 个边,所以要求「多余的边」的数目必须大于等于 components - 1

一个简单的例子如下:

0--1         0--1                0--1
| / => | => | |
2 3 2 3 2 3
components = 2
duplicateEdge = 1

代码实现

class Solution
{
public:
vector<int> root;
int result = 0;
int makeConnected(int n, vector<vector<int>> &connections)
{
int E = connections.size();
// corner cases
if (n == 0 || n == 1)
return 0;
if (E < n - 1)
return -1;
root.resize(n), root.assign(n, -1);
// merge
for (auto &v : connections)
{
int a = v[0], b = v[1];
merge(a, b);
}
int components = count(root.begin(), root.end(), -1);
if (counter >= (components - 1))
return components - 1;
// should not be here
return -1;
}
int find(int x)
{
return root[x] == -1 ? x : (root[x] = find(root[x]));
}
// the number of duplicate edges
int counter = 0;
void merge(int x, int y)
{
x = find(x), y = find(y);
if (x != y)
root[y] = x;
else
{
// there is a duplicate edge
counter++;
}
}
};

等式方程的可满足性

题目[990]:Link.

解题思路

考虑并查集。遍历所有的包含 == 的等式,显然,相等的 2 个变量就合并。对于不等式 x!=y ,必须满足 findroot(x) != findroot(y) 才不会出现逻辑上的错误。也就是说,不相等的 2 个变量必然在不同的连通分支当中。

#define getidx(x) ((x) - 'a')
class Solution
{
public:
vector<int> root;
bool equationsPossible(vector<string> &equations)
{
root.resize('z' - 'a' + 1, -1);
vector<int> notequal;
int len = equations.size();
for (int i = 0; i < len; i++)
{
auto &s = equations[i];
if (s[1] == '!')
{
notequal.emplace_back(i);
continue;
}
int a = getidx(s[0]), b = getidx(s[3]);
merge(a, b);
}
for (int i : notequal)
{
auto &s = equations[i];
int a = getidx(s[0]), b = getidx(s[3]);
if (find(a) == find(b))
return false;
}
return true;
}
int find(int x)
{
return (root[x] == -1) ? x : (root[x] = find(root[x]));
}
void merge(int x, int y)
{
x = find(x), y = find(y);
if (x != y)
root[y] = x;
}
};

尽量减少恶意软件的传播 II

题目[928]:

[leetcode] 并查集(Ⅱ)的更多相关文章

  1. [leetcode] 并查集(Ⅰ)

    预备知识 并查集 (Union Set) 一种常见的应用是计算一个图中连通分量的个数.比如: a e / \ | b c f | | d g 上图的连通分量的个数为 2 . 并查集的主要思想是在每个连 ...

  2. [leetcode] 并查集(Ⅲ)

    婴儿名字 题目[Interview-1707]:典型并查集题目. 解题思路 首先对 names 这种傻 X 字符串结构进行预处理,转换为一个 map,key 是名字,val 是名字出现的次数. 然后是 ...

  3. Leetcode之并查集专题-765. 情侣牵手(Couples Holding Hands)

    Leetcode之并查集专题-765. 情侣牵手(Couples Holding Hands) N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并 ...

  4. Leetcode之并查集专题-684. 冗余连接(Redundant Connection)

    Leetcode之并查集专题-684. 冗余连接(Redundant Connection) 在本问题中, 树指的是一个连通且无环的无向图. 输入一个图,该图由一个有着N个节点 (节点值不重复1, 2 ...

  5. 【LeetCode】并查集 union-find(共16题)

    链接:https://leetcode.com/tag/union-find/ [128]Longest Consecutive Sequence  (2018年11月22日,开始解决hard题) 给 ...

  6. Leetcode题目200.岛屿数量(BFS+DFS+并查集-中等)

    题目描述: 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. 示例 ...

  7. leetcode 76 dp& 强连通分量&并查集经典操作

    800. Similar RGB Color class Solution { int getn(int k){ return (k+8)/17; } string strd(int k){ char ...

  8. Java实现 LeetCode 721 账户合并(并查集)

    721. 账户合并 给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails ...

  9. C#LeetCode刷题-并查集

    并查集篇 # 题名 刷题 通过率 难度 128 最长连续序列   39.3% 困难 130 被围绕的区域   30.5% 中等 200 岛屿的个数   38.4% 中等 547 朋友圈   45.1% ...

随机推荐

  1. python-unittest环境下单独运行一个用例的方法

    在unittest单元测试的框架下,想要调出如图所示的绿三角 需要有两个步骤: 1.确定在工具栏中时在unittest模式下运行的,如果为普通模式的话可以通过下三角下拉修改运行环境: 2.在代码中im ...

  2. python-文件字符分布【get()函数与.sort(key=lambda x:x[0],reverse = False)】

    文件字符分布 描述 统计附件文件的小写字母a-z的字符分布,即出现a-z字符的数量,并输出结果.‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬ ...

  3. 网络流 A - PIGS POJ - 1149 最大流

    A - PIGS POJ - 1149 这个题目我开始感觉很难,然后去看了一份题解,写的很好 https://wenku.baidu.com/view/0ad00abec77da26925c5b01c ...

  4. 2249: Altruistic Amphibians 01背包的应用 + lh的简单图论 图转树求lca

    第一个 写了两个比较简单的数论题目,就是整除理论的两个题目,第一个题目比较蠢,第二个稍微要动一点脑筋 Codeforces Round #347 (Div. 2) – A. Complicated G ...

  5. vtk学习记录(三)——初识vtkRenderer

    目录 前言 vtkRenderer 引入vtk窗口 小结 前言 一场疫情打乱了好多人的节奏,我也一样,一不留神半年都快过去了,这期间虽说一直在鼓捣东西吧,不过确实是没啥实质性的进展,索性就继续把vtk ...

  6. android 防止多次点击,导致事件监听响应到其他界面

    下面有个案例: A点击的时候就跳转到B界面,点击B界面后结束,返回到A界面中 1.此时在B界面中,设置点击事件,点击后结束B v.setOnClickListener(new OnClickListe ...

  7. ES6-10笔记(一)

    大纲 (慕课的图先用着) scope-作用域 作用域是指程序源代码中定义变量的区域,规定了如何查找变量,也就是确定当前执行代码对变量的访问权限. JavaScript作用域共有两种主要的工作模型--词 ...

  8. 如何搭建一个WEB服务器项目(六)—— 上传图片至服务器

    上传图片(用户头像)至服务器 观前提示:本系列文章有关服务器以及后端程序这些概念,我写的全是自己的理解,并不一定正确,希望不要误人子弟.欢迎各位大佬来评论区提出问题或者是指出错误,分享宝贵经验.先谢谢 ...

  9. 「雕爷学编程」Arduino动手做(11)——金属触摸模块

    37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...

  10. Angular知识点复习

    Angular第三方UI组件库(github搜“awesome angular ")-----lonic 概述:是一个第三方的适用于移动端App的UI组件库,可以与Angular/React ...