【高阶数据结构】并查集

并查集

  • 并查集
    • 1、概念
    • 2、根据人找编号 / 根据编号找人(简单介绍一下并查集)
      • (1)代码展示
      • (2)调试结果
    • 3、并查集操作和演示题目
      • (1)并查集操作
        • i、思路
        • ii、总体代码
      • (2)演示题目:省份数量
        • i、做法一:自己写一个并查集
        • ii、做法二:手动版本
      • (3)演示题目:等式方程可满足性


并查集

1、概念

并查集(Union-Find)是一种可以用来判断同属一个集合中相互关联的元素属于几个集合,也可以用来判断图结构中的两点是否是连通, 它也是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。

2、根据人找编号 / 根据编号找人(简单介绍一下并查集)

(1)代码展示

// UnionFindSet.h
#pragma once#include <vector>
#include <map>template <class T>
class UnionFindSet
{
private:std::vector<T> _a;			// 编号找人std::map<T, int> _indexmap; // 人找编号的映射关系
public:UnionFindSet(const T* a, size_t n){for (size_t i = 0; i < n; i++){_a.push_back(a[i]);  // 将传进来的值存入到vector中_indexmap[a[i]] = i; // 映射关系}}
};
// photo.cpp
#include <iostream>
#include "UnionFindSet.h"int main()
{std::string s[] = { "张三", "李四", "王五", "赵六" };UnionFindSet<std::string> ufs(s, 4);return 0;
}

(2)调试结果

在这里插入图片描述

3、并查集操作和演示题目

(1)并查集操作

i、思路

在这里插入图片描述
在这里插入图片描述

ii、总体代码
class UnionFindSet
{
private:std::vector<int> _ufs;
public:UnionFindSet(size_t n): _ufs(n, -1){}// 合并void Union(int x1, int x2){int root1 = FindRoot(x1);int root2 = FindRoot(x2);// 俩根在一颗树上if (root1 == root2) return;// 更新_ufs[root1] += _ufs[root2]; // 前面的值+=后面的值_ufs[root2] = root1; // 更新后面的值为前面的值(双亲根)}// 找根int FindRoot(int x){int parent = x;while (_ufs[parent] >= 0){parent = _ufs[parent]; // 下标和值的关系}return parent;}// 判断是否是同一个树bool IsSet(int x1, int x2){return FindRoot(x1) == FindRoot(x2);}// 算树的数量int Size(){int n = _ufs.size();int size = 0;for (int i = 0; i < n; i++){if (_ufs[i] < 0){size++;}}return size;}
};

(2)演示题目:省份数量

i、做法一:自己写一个并查集

leetcode题目链接跳转
在这里插入图片描述

class UnionFindSet
{
private:std::vector<int> _ufs;
public:UnionFindSet(size_t n): _ufs(n, -1){}// 合并void Union(int x1, int x2){int root1 = FindRoot(x1);int root2 = FindRoot(x2);// 俩根在一颗树上if (root1 == root2) return;// 更新_ufs[root1] += _ufs[root2]; // 前面的值+=后面的值_ufs[root2] = root1; // 更新后面的值为前面的值(双亲根)}// 找根int FindRoot(int x){int parent = x;while (_ufs[parent] >= 0){parent = _ufs[parent]; // 下标和值的关系}return parent;}// 判断是否是同一个树bool IsSet(int x1, int x2){return FindRoot(x1) == FindRoot(x2);}// 算树的数量int Size(){int n = _ufs.size();int size = 0;for (int i = 0; i < n; i++){if (_ufs[i] < 0){size++;}}return size;}
};
class Solution 
{
public:int findCircleNum(vector<vector<int>>& isConnected) {UnionFindSet ufs(isConnected.size());for (int i = 0; i < isConnected.size(); i++){for (int j = 0; j < isConnected[i].size(); j++){if (isConnected[i][j] == 1){ufs.Union(i, j);}}}return ufs.Size();}
};
ii、做法二:手动版本
class Solution 
{
public:int findCircleNum(vector<vector<int>>& isConnected) {vector<int> ufs(isConnected.size(), -1);// lambda表达式auto FindRoot = [&ufs](int x) {while (ufs[x] >= 0) x = ufs[x];return x;};for (int i = 0; i < isConnected.size(); i++){for (int j = 0; j < isConnected[i].size(); j++){if (isConnected[i][j] == 1){int root1 = FindRoot(i);int root2 = FindRoot(j);if (root1 != root2){ufs[root1] += ufs[root2];ufs[root2] = root1;}}}}int n = 0;for (auto e : ufs){if (e < 0)n++;}return n;}
};

(3)演示题目:等式方程可满足性

leetcode题目链接跳转

在这里插入图片描述
进行两次遍历,第一次遍历假如说是中间是等号的情况下的话,就将俩字母都放到同一个集合中,第二次遍历假如说是中间是不等号的情况下的话,就判断俩字母是否是在同一个集合中,在的话就返回false,不在的话就返回true。

class Solution 
{
public:bool equationsPossible(vector<string>& equations) {vector<int> ufs(26, -1);// lambda表达式auto FindRoot = [&ufs](int x) {while (ufs[x] >= 0) x = ufs[x];return x;};// 第一遍遍历将相同的字母都放到同一个集合中for (auto& str : equations){if (str[1] == '='){int root1 = FindRoot(str[0] - 'a');int root2 = FindRoot(str[3] - 'a');if (root1 != root2){ufs[root1] += ufs[root2];ufs[root2] = root1;}}}// 第二遍遍历,遇到相同的俩字母在一个集合中就返回falsefor (auto& str : equations){if (str[1] == '!'){int root1 = FindRoot(str[0] - 'a');int root2 = FindRoot(str[3] - 'a');if (root1 == root2){return false;}}}return true;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/320060.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Tokitsukaze and Average of Substring

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 前缀和。 开一个int类型的前缀和数组pre[30][N]&#xff08;pre[i][j]表示某字符转成的数字 i 在一段区间的前缀个数。因为字母表有‘a’~z…

【Unity 组件思想-预制体】

【Unity 组件思想-预制体】 预制体&#xff08;Prefab&#xff09;是Unity中一种特殊的组件 特点和用途&#xff1a; 重用性&#xff1a; 预制体允许开发者创建可重复使用的自定义游戏对象。这意味着你可以创建一个预制体&#xff0c;然后在场景中多次实例化它&#xff0c;…

猿人学第七题-动态字体-随风漂移

前言&#xff1a;该题主要是考对fontTools.ttLib.TTFont的操作&#xff0c;另外就是对字典互相映射的操作 一、woff文件存储 from fontTools.ttLib import TTFont #pip install fontTools def save_woff(response):woff response[woff]woff_file base64.b64decode(woff.enc…

Java Jackson-jr 库是干什么用的

Jackson-jr 是一个轻量级的Java JSON 处理库。这个库被设计用来替代 Jackson 的复杂性。对比 Jackson 的复杂 API&#xff0c;Jackson-jr 的启动速度更快&#xff0c;包大小更小。 虽然Jackson databind&#xff08;如ObjectMapper&#xff09;是通用数据绑定的良好选择&#…

uniapp动态设置Tabbar

一套小程序及app可能会有多个用户角色&#xff0c;多者能看到的内容应该是不一样的。 实现原理 舍弃uniapp原生的tabbar&#xff0c;使用uView插件下的u-tabbar导航插件来实现。介绍 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架uView UI&#xff0c;是…

JavaScript百炼成仙自学笔记——2

一、循环遍历&#xff1a; 方式一 for(var i0;i<10;i){console.log(i); }方式二 var i 0; while(i < 100){console.log(i);i; }细看代码就是 先定义变量i&#xff0c;再执行{}中的代码&#xff0c;最后改循环变量的值 二、遍历 什么事遍历&#xff1f; 什么时候会用…

CMakeLists.txt语法规则:部分常用命令说明四

一. 简介 前面几篇文章学习了CMakeLists.txt语法中前面几篇文章学习了CMakeLists.txt语法中部分常用命令。文章如下&#xff1a; CMakeLists.txt语法规则&#xff1a;部分常用命令说明一-CSDN博客 CMakeLists.txt语法规则&#xff1a;部分常用命令说明二-CSDN博客 CMakeLi…

基于springboot+vue+Mysql的自习室预订系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

谈谈Tcpserver开启多线程并发处理遇到的问题!

最近在学习最基础的socket网络编程&#xff0c;在Tcpserver开启多线程并发处理时遇到了一些问题&#xff01; 说明 在linux以及Windows的共享文件夹进行编写的&#xff0c;所以代码中有的部分使用 #ifdef WIN64 ... #else ... #endif 进入正题&#xff01;&#xff01;&…

Unity Navigation 入门(新版)

概述 在游戏的制作过程中&#xff0c;寻路功能一定是非常重要的部分&#xff0c;他可以为主角寻路&#xff0c;也可以运用到敌人追击等&#xff0c;相比于自己实现的难度&#xff0c;使用寻路组件就显得简单的多&#xff0c;那接下来就开始学习这部分的内容吧 1.安装AI Naviga…

MySQL 运维篇

回顾基本语句&#xff1a; 数据定义语言(DDL) 这类语言用于定义和修改数据库的结构&#xff0c;包括创建、删除和修改数据库、 表、视图和索引等对象。 主要的语句关键字包括 CREATE 、 DROP 、 ALTER 、 RENAME 、 TRUNCATE 等。 create database 数据库 &#xff1b; cr…

关于AIGC发展历程的研究报告(原创文章)

摘要&#xff1a; 2022年&#xff0c;Chat GPT和Stable Diffusion展现了AIGC强大的技术实力&#xff0c;拉开了AIGC时代的帷幕。2023年&#xff0c;GPT-4、Midjourney V5等又掀起了人工智能的热潮&#xff0c;2024年2月15日&#xff08;美国当地时间&#xff09;正式对外发布的…

代码随想录day51 | 动态规划P12 | ● 309. ● 714. ●买卖股票总结

309.最佳买卖股票时机含冷冻期 给定一个整数数组 prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;: 卖出股票后&…

《21天学通C++》(第十一章)多态

为什么需要多态&#xff1f; 为了最大限度地减少代码&#xff0c;提高可读性 1.虚函数 虚函数是C中的一种特殊成员函数&#xff0c;它允许在派生类&#xff08;也称为子类&#xff09;中重写&#xff08;覆盖&#xff09;基类的实现&#xff0c;使用virtual进行声明 在C中&am…

【Java EE】多线程(二)Thread 类与常用方法

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…

【Qt QML】Frame组件

Frame&#xff08;框架&#xff09;包含在&#xff1a; import QtQuick.Controls继承自Pane控件。用于在可视框架内布局一组逻辑控件。简单来说就是用来包裹和突出显示其他可视元素。Frame不提供自己的布局&#xff0c;但需要自己对元素位置进行设置和定位&#xff0c;例如通过…

【JavaEE 初阶(二)】线程安全问题

❣博主主页: 33的博客❣ ▶️文章专栏分类:JavaEE◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多线程知识 目录 1.前言2.synchronized2.1例子2.2synchronized修饰代码块2.3 synchronized修饰方法2.4sy…

python中怎么清屏

一、“Windows命令行窗口”下清屏&#xff0c;可用下面两种方法&#xff1a; 第一种方法&#xff0c;在命令行窗口输入&#xff1a; import os ios.system("cls") 第二种方法&#xff0c;在命令行窗口输入&#xff1a; import subprocess isubprocess.call("cl…

数据结构--链表进阶面试题

在链表题目开始之前我们来复习一道数组元素的逆序问题&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 提示&#xff1a; 1 < nums.length < 10^5-2^31 < nums[i] < 2^31 - 10 < k < 10^5 思…

微信小程序之搜索框样式(带源码)

一、效果图&#xff1a; 点击搜索框&#xff0c;“请输入搜索内容消失”&#xff0c;可输入关键字 二、代码&#xff1a; 2.1、WXML代码&#xff1a; <!--搜索框部分--><view class"search"><view class"search-btn">&#x1f50d;&l…