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 ...
随机推荐
- jvm垃圾收集器汇总
1.吞吐量和延时 吞吐量:吞吐量指的是cpu的利用时间,计算公式是 运行用户代码时间 / (用户代码时间 + 垃圾收集时间),吞吐量越大说明cpu的利用率越大. 延时:延时指的是停顿时间,用户代码不 ...
- 两步解决macbook电池不充电
问题描述: 1.电源适配器是冷的,判断并没有充电,更换拔插笔记本的不同TypeC插口问题依然.(怀疑适配器坏了,但心想Apple质量一个适配器不至于那么不抗用) 2.偶尔能开起来机,则显示电源3%,瞬 ...
- django+ajax实现xlsx文件下载功能
前端代码 $("#id_pullout").click(function () { //发送ajax请求 $.ajax({ url: '/pullout/', //请求的url m ...
- obs推流核心流程分析
前置步骤和录屏是一样的,见我的上一篇文章 https://www.cnblogs.com/billin/p/17219558.html bool obs_output_actual_start(obs ...
- MyBatisPlus 逻辑删除演示
一.数据库 数据库中添加逻辑删除字段:
- Feeder 一款 Mac 上的 RSS 阅读器,更优雅地跟踪最新的新闻和博客文章
Feeder 是一款 Mac 上的 RSS 阅读器,它可以帮助用户轻松地订阅和管理 RSS 源,让用户可以轻松地跟踪最新的新闻和博客文章. 下载: FeederMac ⇲ 详细了解 Feeder 的界 ...
- Rancher 系列文章-Rancher 对接 Active Directory 实战
概述 只要是个公司,基本上都有邮箱和 AD(Active Directory). 在 AD 里,已经有了: 用户 账号密码 邮箱 用户组 组织架构 所以对于一些仅限于本公司一定范围内人员使用的管理或后 ...
- it必给装机小软件附源码
需要的包 启动之后是这个样子的 远吗如下: #authon fengimport zipfile as zfimport osimport win32apiimport win32conimport ...
- [Tomcat/Java EE/Linux]Tomcat启动异常:StandardServer.await: create[localhost:8005]: java.net.BindException: 无法指定被请求的地址
1 问题背景 部门新成员小J在一台虚拟机(ip:192.168.191.96)内安装部署部门的数据治理产品(含: 20余个微服务模块 + 1套(用户)基础管理系统BMS). 小J启动BMS的Tomca ...
- Go For Web:踏入Web大门的第一步——Web 的工作方式
前言: 本文作为解决如何通过 Golang 来编写 Web 应用这个问题的前瞻,对 Golang 中的 Web 基础部分进行一个简单的介绍.目前 Go 拥有成熟的 Http 处理包,所以我们去编写一个 ...