2023-04-14:n对情侣坐在连续排列的 2n 个座位上,想要牵到对方的手, 人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的ID, 情侣们按顺序编号,第一对
2023-04-14:n对情侣坐在连续排列的 2n 个座位上,想要牵到对方的手,
人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的ID,
情侣们按顺序编号,第一对是 (0, 1),第二对是 (2, 3),以此类推,最后一对是 (2n-2, 2n-1)。
返回 最少交换座位的次数,以便每对情侣可以并肩坐在一起。
每次交换可选择任意两人,让他们站起来交换座位。
输入: row = [0,2,1,3]。
输出: 1。
输入: row = [3,2,0,1]。
输出: 0。
答案2023-04-14:
大体过程如下:
定义并查集结构体 UnionFind,包括父节点数组 father、子树大小数组 size、辅助数组 help 和当前连通分量数 sets。
实现并查集结构体的三个方法:
a. 初始化方法 new,初始化父节点数组和子树大小数组,并将父节点数组的值初始化为自身,连通分量数初始为节点数量。
b. 查找方法 find,通过不断向上寻找父节点,直到找到根节点,并压缩路径优化查找效率。
c. 合并方法 union,找到 i 和 j 所在的连通分量的代表元素 fi 和 fj,以子树大小来优化合并操作,并更新连通分量数。
实现计算最少交换座位次数的函数 min_swaps_couples,首先获取座位数量 n,然后初始化并查集 uf,遍历相邻的座位,将情侣所在的连通分量合并。最后返回需要交换座位的最小次数。
在 main 函数中分别调用 min_swaps_couples 函数,传入测试数据,并输出最少交换座位的次数。
根据测试数据 row = [0, 2, 1, 3],第一对情侣坐在座位0和1上,第二对情侣坐在座位2和3上,因此已经满足牵手的条件。而在测试数据 row = [3, 2, 0, 1] 中,第一对情侣坐在座位3和2上,第二对情侣坐在座位0和1上,因此需要交换他们的座位才能满足牵手的条件。
并查集的初始化时间复杂度为O(n),其中n为节点数量。在计算最少交换座位次数的函数 min_swaps_couples 中,遍历相邻的座位需要O(n) 的时间,每次调用并查集中的 find 方法和 union 方法的时间复杂度均为O(α(n)),其中α(n) 是阿克曼函数的反函数,它比对数函数增长得慢,可以近似看作常数级别。因此,总时间复杂度为O(nα(n))。
空间复杂度取决于节点数量,需要使用O(n) 的空间存储父节点数组、子树大小数组和辅助数组。
rust代码如下:
// 定义并查集结构体
struct UnionFind {
father: Vec<i32>, // 父节点数组
size: Vec<i32>, // 子树大小数组
help: Vec<i32>, // 辅助数组,用于优化路径压缩操作
sets: i32, // 当前连通分量数
}
impl UnionFind {
// 初始化并查集
fn new(n: i32) -> Self {
let mut father = vec![0; n as usize]; // 初始化父节点数组
let size = vec![1; n as usize]; // 初始化子树大小数组
for i in 0..n {
father[i as usize] = i; // 父节点初始化为自身
}
UnionFind {
father, // 返回新建的并查集结构体
size,
help: vec![0; n as usize],
sets: n, // 初始时连通分量数为n
}
}
// 查找i所在连通分量的代表元素
fn find(&mut self, mut i: i32) -> i32 {
let mut hi = 0;
while i != self.father[i as usize] {
// 不断向上寻找父节点,直到找到根节点
self.help[hi] = i; // 将当前节点压入辅助数组中
hi += 1;
i = self.father[i as usize]; // 向上跳一步
}
for j in (0..hi).rev() {
// 压缩路径
self.father[self.help[j] as usize] = i; // 将辅助数组中的节点的父节点设为根节点
}
i // 返回根节点
}
// 合并i和j所在的连通分量
fn union(&mut self, i: i32, j: i32) {
let fi = self.find(i); // 找到i的代表元素
let fj = self.find(j); // 找到j的代表元素
if fi != fj {
// 如果i和j不在同一个连通分量中
if self.size[fi as usize] >= self.size[fj as usize] {
// 以树的大小来优化合并操作
self.father[fj as usize] = fi; // 将fj的父节点设为fi
self.size[fi as usize] += self.size[fj as usize]; // 更新fi子树的大小
} else {
self.father[fi as usize] = fj; // 将fi的父节点设为fj
self.size[fj as usize] += self.size[fi as usize]; // 更新fj子树的大小
}
self.sets -= 1; // 连通分量数减1
}
}
// 获取当前连通分量数
fn sets(&self) -> i32 {
self.sets
}
}
// 计算最少交换座位的次数
fn min_swaps_couples(row: Vec<i32>) -> i32 {
let n = row.len() as i32; // 座位数量
let mut uf = UnionFind::new(n / 2); // 初始化并查集
for i in (0..n).step_by(2) {
// 遍历相邻的座位
uf.union(row[i as usize] / 2, row[(i + 1) as usize] / 2); // 合并情侣所在的连通分量
}
n / 2 - uf.sets() // 返回需要交换座位的最小次数
}
fn main() {
let row = vec![0, 2, 1, 3];
let swaps = min_swaps_couples(row);
println!("Minimum swaps required: {}", swaps); // Output: Minimum swaps required: 1
let row = vec![3, 2, 0, 1];
let swaps = min_swaps_couples(row);
println!("Minimum swaps required: {}", swaps); // Output: Minimum swaps required: 0
}

2023-04-14:n对情侣坐在连续排列的 2n 个座位上,想要牵到对方的手, 人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的ID, 情侣们按顺序编号,第一对的更多相关文章
- 有一个直方图,用一个整数数组表示,其中每列的宽度为1,求所给直方图包含的最大矩形面积。比如,对于直方图[2,7,9,4],它所包含的最大矩形的面积为14(即[7,9]包涵的7x2的矩形)。给定一个直方图A及它的总宽度n,请返回最大矩形面积。保证直方图宽度小于等于500。保证结果在int范围内。
// ConsoleApplication5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<vector> ...
- LeetCode 周赛 342(2023/04/23)容斥原理、计数排序、滑动窗口、子数组 GCB
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 大家好,我是小彭. 前天刚举办 2023 年力扣杯个人 SOLO 赛,昨天周赛就出了一场 Easy - Ea ...
- CVE-2015-1328 Ubuntu 12.04, 14.04, 14.10, 15.04 overlayfs Local Root
catalog . 引言 . Description . Effected Scope . Exploit Analysis . Principle Of Vulnerability . Patch ...
- 如何教你在NIPS会议上批量下载历年的pdf文档(另附04~14年NIPS论文下载链接)
如何获得NIPS会议上批量下载的链接? NIPS会议下载网址:http://papers.nips.cc/ a.点击打开上述网站,进入某一年的所有会议,例如2014年,如下图 b.然后对着当前网页点击 ...
- Ubuntu LTS 系统学习使用体会和实用工具软件汇总 6.04 8.04 10.04 12.04 14.04 16.04
Ubuntu LTS 系统学习体会和工具软件汇总 6.04 8.04 10.04 12.04 14.04 16.04 ubuntu入门必备pdf:http://download.csdn.net/de ...
- 14.9 InnoDB Row Storage and Row Formats InnoDB 行存储和行格式:
14.9 InnoDB Row Storage and Row Formats InnoDB 行存储和行格式: 14.9.1 Overview of InnoDB Row Storage 14.9.2 ...
- Ubuntu 14.04/14.10下安装VMware Workstation 11图文教程
VMware workstation 是一个可以进行桌面操作的虚拟软件.它可以让我们在一台电脑或者虚拟机中运行多个虚拟机. 由VMware公司研发和维护.由于是商业软件,我们需要买他们家的许可证或者说 ...
- [转] Ubuntu 14.04/14.10下安装VMware Workstation 11图文教程
点击这里查看原文 译者:GuiltyMan 本文由 Linux公社翻译组 原创翻译 Linux公社 诚意奉献 更多请访问此处博客网站 VMware workstation 是一个可以进行桌面操作的虚 ...
- 安装ubuntu出现BUG soft lockup的解决方法(16.04 14.04)
对于16.04而言,当时用的是UtrISO 安装的,导致安装过程用会出现 “not a com32r image” 的错误,解决方法见上文的: boot: live 华硕Z9主板安装16.04以上系统 ...
- 每日一练ACM 2019.04.14
2019.4.14 第1001题:Sum Problem Problem DescriptionHey, welcome to HDOJ(Hangzhou Dianzi University Onli ...
随机推荐
- TCP长连接管道通信改消息队列涉及到的知识点
1.队列,链表,STL 1.C++ STL标准库简介 长久以来,软件界一直希望建立一种可重复利用的东西,以及一种得以制造出"可重复运用的东西" 的方法,从函数(functions) ...
- IDEA中使用JDBC连接MySQL数据库报错:No appropriate protocol (protocol is disabled or cipher suites are inappropriate) 的解决方法
在IDEA中使用JDBC连接MySQL,程序运行之后报错: 定位到第16行: 根据上面报错提示,在url参数字段最前面添加参数 useSSL=false : 再次运行程序,成功连接到数据库!
- windows作业系统部署nfs服务
文件共享的需求是如何产生的? 据说当年美国和苏联冷战期间,双方都有摧毁对方的能力.而苏联 不怕死的性格让美国人多少有些害怕.美国当时害怕自己的军事指挥中心被苏联摧毁.于是,美国建立了阿帕网,并把自己的 ...
- 基于springboot实现SSM整合
(1)SpringBoot整合Spring(不存在) (2)SpringBoot整合SpringMVC(不存在) (3)SpringBoot整合MyBatis(主要) 一.新建springboot项目 ...
- java注解与反射--2
java注解与反射--2 反射:java.Reflection 因为反射,使java具有了一定的动态性. java反射机制概述 动态语言: 是一类在运行时可以改变其结构的语言:例如新的函数.对象.甚至 ...
- CSAPP-Architecture Lab
Part A 前置准备 gcc -Wall -O1 -g -c yis.c gcc -Wall -O1 -g -c isa.c gcc -Wall -O1 -g yis.o isa.o -o yis ...
- 自己动手从零写桌面操作系统GrapeOS系列教程——24.加载并运行loader
学习操作系统原理最好的方法是自己写一个简单的操作系统. 之前我们在电脑的启动过程中介绍过boot程序的主要任务就是加载并运行loader程序,本讲我们就来实现. 本讲代码文件共2个: boot.asm ...
- Mac基本命令操作
Mac使用常见命令 删除空目录:rmdir 目录 删除文件夹:rm -rf 文件夹 创建一个文件夹:mkdir 文件名 创建一个文件:touch 文件 修改一个文件:vi 文件名 重命名文件 mv 原 ...
- 算法题学习链路简要分析与面向 ChatGPT 编程
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 声明:此图片由 MidJourney 生成 未经训练,不属于任何真实人物 大家好,我是小彭. 2023 开年 ...
- [ACM]queue队列模板
思路 队列的原理基本与站队一样,队首出,队尾入,变化以后也是大同小异,写起来主要就是注意struct的相关知识,以及伪指针(分别指向队首和队尾+1),队尾序号要+1以防首位变量数字重合造成不必要的麻烦 ...