最长连续序列

题目[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. 基本Linux命令(上)

           Linux的难点在于我们需要记忆大量的命令及参数.如有问题请批评指正,在下感激不尽.        Linux的命令都是在shell下使用的,也就是我们常说的终端(Terminal).包 ...

  2. Angular 从入坑到挖坑 - Router 路由使用入门指北

    一.Overview Angular 入坑记录的笔记第五篇,因为一直在加班的缘故拖了有一个多月,主要是介绍在 Angular 中如何配置路由,完成重定向以及参数传递.至于路由守卫.路由懒加载等&quo ...

  3. 【Kafka】数据分区策略

    数据分区策略 四种策略 一.指定分区号,数据会直接发送到所指定的分区 二.没有指定分区号,指定了数据的key,可以通过key获取hashCode决定数据发送到哪个分区 三.都没有指定的话,会采取rou ...

  4. 【Java基础总结】Java基础语法篇(上)

    Java基础语法 思维导图 一.Java语言介绍 1.Java应用平台 JavaSE(Java Platform Standard Edition):开发普通桌面和商务应用程序,是另外两类的基础 Ja ...

  5. FreeAnchor:抛弃单一的IoU匹配,更自由的anchor匹配方法 | NIPS 2019

    论文抛弃以往根据IoU硬性指定anchor和GT匹配关系的方法,提出FreeAnchor方法来进行更自由的匹配,该方法将目标检测的训练定义为最大似然估计(MLE)过程,端到端地同时学习目标分类.目标检 ...

  6. OpenCV 3.4.2 Windows系统下的环境搭建(附带opencv_contrib-3.4.2)

    前言 当前需要回到Windows平台下进行开发,在win10系统上搭建了编译opencv3.4.2的环境,并添加opencv_contrib-3.4.2的模块,以下是本文所需要的软件以及源码. 系统: ...

  7. Altera特殊管脚的使用

  8. HDU 2017 (水)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2017 题目大意:给你段字符串,求出字符串中含有数字字符的个数 解题思路: 字符串输入输出的基本应用:h ...

  9. JSP+Servlet+JDBC+mysql实现的个人日记本系统

    项目简介 项目来源于:https://gitee.com/wishwzp/Diary 本系统基于JSP+Servlet+Mysql 一个基于JSP+Servlet+Jdbc的个人日记本系统.涉及技术少 ...

  10. 2018-08-27 jq筛选选择器

    筛选选择器:为了辅助选择器更简便.快速的找到元素: 1.过滤 eq(n) -> 第n个元素(从零开始) $('h1').eq(2) // 第三个h1 first() -> 第一个元素 la ...