【题解 | 双端队列】天梯赛练习集:重排链表

2024-04-17 16:28

本文主要是介绍【题解 | 双端队列】天梯赛练习集:重排链表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

重排链表

给定一个单链表 L 1 → L 2 → . . . → L n − 1 → L n L_1 \to L_2 \to ...\to L_{n-1}\to L_n L1L2...Ln1Ln,将其重新排列后变为 L 1 → L n → L 2 → L n − 1 → L 3 → L n − 2 . . . L_1 \to L_n \to L_2 \to L_{n-1} \to L_3 \to L_{n-2} ... L1LnL2Ln1L3Ln2...,例如:给定 L L L 1 → 2 → 3 → 4 → 5 → 6 1→2→3→4→5→6 123456 ,则输出应该为 6 → 1 → 5 → 2 → 4 → 3 6→1→5→2→4→3 615243

输入格式:

每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址和结点总个数,即正整数 N ( ≤ 1 0 5 ) N (≤10^5 ) N(105)。结点的地址是5位非负整数,NULL地址用−1表示。

接下来有N行,每行格式为:

Address Data Next

其中Address是结点地址;Data是该结点保存的数据,为不超过 1 0 5 10^5 105 的正整数;Next是下一结点的地址。题目保证给出的链表上至少有两个结点。

输出格式:

对每个测试用例,顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。

输入样例:

00100 6
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

输出样例:

68237 6 00100
00100 1 99999
99999 5 12309
12309 2 00000
00000 4 33218
33218 3 -1

解题思路:

这个问题可以通过使用双端队列来解决。首先,我们将链表中的所有节点按照原始顺序添加到双端队列中。然后,我们交替从双端队列的前端和后端取出节点并将它们连接起来,就得到了所需的链表。

当然,使用两个栈也是一样的。

#include <bits/stdc++.h>
using namespace std;struct Node {int address, data, next;int order = 2 * 100000;  // 初始化节点顺序为一个较大的数
} nodes[100000];// 比较函数,用于按照节点顺序排序
bool cmp(Node a, Node b) {return a.order < b.order;
}int main() {int begin, n, address;cin >> begin >> n;  // 读取链表开始地址和节点数量for (int i = 0; i < n; i++) {cin >> address;  // 读取节点地址cin >> nodes[address].data >> nodes[address].next;  // 读取节点数据和下一个节点地址nodes[address].address = address;  // 记录节点地址}int count = 0;// 遍历链表,记录节点顺序while (begin != -1) {nodes[begin].order = count++;begin = nodes[begin].next;}// 按照节点顺序排序sort(nodes, nodes + 100000, cmp);deque<Node> dq;// 将节点按照顺序添加到双端队列中for (int i = 0; i < count; i++) {dq.push_back(nodes[i]);}vector<Node> ans;// 交替从双端队列的前端和后端取出节点while (!dq.empty()) {ans.push_back(dq.back());dq.pop_back();if (!dq.empty()) {ans.push_back(dq.front());dq.pop_front();}}// 输出重新排列后的链表for (size_t i = 0; i < ans.size() - 1; i++) {printf("%05d %d %05d\n", ans[i].address, ans[i].data, ans[i + 1].address);}// 输出最后一个节点printf("%05d %d -1\n", ans[ans.size() - 1].address, ans[ans.size() - 1].data);return 0;
}

测试链接:重排链表

这篇关于【题解 | 双端队列】天梯赛练习集:重排链表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/912286

相关文章

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2

C++ RabbitMq消息队列组件详解

《C++RabbitMq消息队列组件详解》:本文主要介绍C++RabbitMq消息队列组件的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C++客户端库4. A

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time

Java的栈与队列实现代码解析

《Java的栈与队列实现代码解析》栈是常见的线性数据结构,栈的特点是以先进后出的形式,后进先出,先进后出,分为栈底和栈顶,栈应用于内存的分配,表达式求值,存储临时的数据和方法的调用等,本文给大家介绍J... 目录栈的概念(Stack)栈的实现代码队列(Queue)模拟实现队列(双链表实现)循环队列(循环数组

Redis消息队列实现异步秒杀功能

《Redis消息队列实现异步秒杀功能》在高并发场景下,为了提高秒杀业务的性能,可将部分工作交给Redis处理,并通过异步方式执行,Redis提供了多种数据结构来实现消息队列,总结三种,本文详细介绍Re... 目录1 Redis消息队列1.1 List 结构1.2 Pub/Sub 模式1.3 Stream 结

SpringKafka错误处理(重试机制与死信队列)

《SpringKafka错误处理(重试机制与死信队列)》SpringKafka提供了全面的错误处理机制,通过灵活的重试策略和死信队列处理,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、Spring Kafka错误处理基础二、配置重试机制三、死信队列实现四、特定异常的处理策略五

Spring Boot整合消息队列RabbitMQ的实现示例

《SpringBoot整合消息队列RabbitMQ的实现示例》本文主要介绍了SpringBoot整合消息队列RabbitMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装Spring

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定