【每日一题】2019考研数据结构 - 重新排列单链表

给定一个线性表 L = ( a 1 , a 2 , a 3 , … , a n − 2 , a n − 1 , a n ) L = (a_1, a_2, a_3, \dots, a_{n-2}, a_{n-1}, a_n) L=(a1,a2,a3,,an2,an1,an),它采用带头结点的单链表存储。设计一个空间复杂度为 O ( 1 ) O(1) O(1) 且时间尽可能高效的算法,重新排列链表中的节点,得到新的线性表 L ′ = ( a 1 , a n , a 2 , a n − 1 , … ) L' = (a_1, a_n, a_2, a_{n-1}, \dots) L=(a1,an,a2,an1,)

要求

  1. 给出算法的基本设计思想。
  2. 根据设计思想,采用 C 或 C++ 语言描述算法,并在关键部分给出注释。
  3. 说明设计的算法的时间复杂度和空间复杂度。

本文需要用到快慢指针与时空复杂度的知识点,若您不清楚,可参考以下文章:

  • 【数据结构】快慢指针探秘:理解链表与数组中的环结构
  • 【数据结构】时间复杂度和空间复杂度是什么?

设计思想

该问题的核心是重新排列单链表,使得其从前往后依次为:第一个元素、最后一个元素、第二个元素、倒数第二个元素,依此类推。为了满足题目对空间复杂度 O(1) 的要求,我们不能使用额外的数据结构(如栈或数组),只能通过指针操作来完成。

解题步骤:

  1. 找到链表的中间节点:使用快慢指针找到链表的中点位置。
  2. 反转后半部分链表:从中点位置开始,反转链表的后半部分,使得最后一个节点变为新的起始节点。
  3. 合并前后两部分链表:按照题目要求,将反转后的链表节点依次插入到前半部分链表中,得到重新排列后的链表。

算法实现(C++代码)

以下是该算法的实现代码,代码中包含了详细注释。特别是最后的 while 循环部分,进行了交替合并操作:

#include "bits/stdc++.h"
using namespace std;struct Node {int value;Node* next;
};// 反转链表函数
Node* reverseNode(Node* node) {Node* cur = nullptr, *newNode = nullptr;while (node) {newNode = node;node = node->next;newNode->next = cur;cur = newNode;}return cur;
}Node* rearrangeList(Node* head) {if (!head || !head->next || !head->next->next) return head;// 使用快慢指针找到链表的中间节点Node* slow = head;Node* fast = head;while (fast && fast->next && fast->next->next) {slow = slow->next;fast = fast->next->next;}// 将链表后半部分反转Node* reversedHalf = reverseNode(slow->next);slow->next = nullptr;  // 将前半部分和后半部分断开// 合并链表的两部分Node* result = head;while (reversedHalf) {Node* up = result;       // 前半部分当前节点Node* down = reversedHalf; // 后半部分当前节点reversedHalf = reversedHalf->next;  // 更新后半部分节点指针// 将后半部分的节点插入到前半部分的当前位置之后down->next = up->next;up->next = down;result = down->next;  // 移动到下一个位置}return head;
}

代码讲解

  1. 找到链表的中间节点:快慢指针 fastslow 用于定位链表的中间位置。每次 fast 移动两步,slow 移动一步,当 fast 到达链表末尾时,slow 刚好到达中间位置。这样找中间节点的时间复杂度为 O(n/2) ≈ O(n)。

  2. 反转链表的后半部分reverseNode 函数用于将链表的后半部分反转。它通过三指针法:nodecurnewNode 实现链表反转,使得最后一个节点成为新的起始节点。

  3. 合并链表while 循环执行链表合并操作。合并过程中,我们交替地将前半部分和反转后的后半部分节点串联起来,形成要求的排列顺序。

    特别说明 while 循环

    • up 是当前前半部分的节点,而 down 是当前反转后链表的节点。
    • 我们将 down 节点插入到 up 后面,并调整指针使得链表按照所需顺序排列。
    • 为了保证链表结构不被破坏,我们先将 reversedHalf 更新为下一个节点,以防在操作 down->next 时丢失链表的后续节点。

与其他实现方式的比较

  • 递归实现:可以通过递归反向合并链表的前半部分和后半部分,但递归会带来 O(n) 的额外栈空间,不满足 O(1) 的空间复杂度要求。
  • 使用栈或数组:虽然可以用栈或数组存储链表元素位置并重新排列,但也会增加 O(n) 的空间复杂度。
  • 原地操作:我们当前的实现方式通过反转链表和指针操作完成,达到了 O(1) 的空间复杂度要求,是最优解法。

时间和空间复杂度分析

  • 时间复杂度

    • 找中间节点的操作复杂度为 O(n)。
    • 反转链表后半部分的复杂度为 O(n/2) ≈ O(n)。
    • 合并链表的复杂度为 O(n)。
    • 总体时间复杂度为 O(n)。
  • 空间复杂度

    • 该算法仅使用几个指针变量,空间复杂度为 O(1),不需要额外的空间存储。

总结

该算法通过使用快慢指针找到链表的中点位置,再反转后半部分链表,并依次将节点合并至前半部分,从而实现了题目所要求的重排。此方法不仅保证了 O(n) 的时间复杂度,也达到了 O(1) 的空间复杂度。

这种解法在面试和考试中是一个常见的考点,理解这个方法将帮助你在遇到类似链表问题时迅速找到高效的解决方案。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

D65【python 接口自动化学习】- python基础之数据库

day65 SQL-DQL-分组聚合 学习日期:20241111 学习目标:MySQL数据库-- 133 SQL-DQL-分组聚合 学习笔记: 分组聚合 总结 分组聚合的语法 分组聚合的注意事项 group by 中出现了哪个列,哪个列才能出现在select中的非聚合中

初学mongoDB

MongoDB 是一个开源的 NoSQL 数据库,由 C 语言编写。它与传统的关系型数据库不同,MongoDB 使用的是一种基于文档的存储模型,不需要定义固定的表结构,可以灵活地存储和管理大量的非结构化数据。下面是 MongoDB 的一些核心特性&…

DAY59||并查集理论基础 |寻找存在的路径

并查集理论基础 并查集主要有两个功能&#xff1a; 将两个元素添加到一个集合中。判断两个元素在不在同一个集合 代码模板 int n 1005; // n根据题目中节点数量而定&#xff0c;一般比节点数量大一点就好 vector<int> father vector<int> (n, 0); // C里的一…

基于Spring Boot的乡政府管理系统设计与实现,LW+源码+讲解

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装乡政府管理系统软件来发挥其高效地信息处理的作用&#xf…

【NLP】使用 PyTorch 从头构建自己的大型语言模型 (LLM)

读完这篇文章后&#xff0c;你会取得什么成就&#xff1f;你将能够自己构建和训练大型语言模型 (LLM)&#xff0c;同时与我一起编写代码。虽然我们正在构建一个将任何给定文本从英语翻译成马来语的 LLM&#xff0c;但你可以轻松地修改此 LLM 架构以用于其他语言翻译任务。 LLM…

QT打包应用程序文件步骤

QT应用程序&#xff08;.exe&#xff09;打包复制到其他电脑 在QT程序在自己电脑编译好了后&#xff0c;需要打包给其他人。这里介绍一下详细步骤&#xff1a; 确定编译器 搜了很多相关的打包教程&#xff0c;但是还是会出现“应用程序无法正常启动(0xc000007b)”这类错误。经过…

JMeter进阶篇

目录 上篇导航&#xff1a; 总目录&#xff1a; 一、逻辑控制器&#xff1a; 1.逻辑控制器和关联&#xff1a; 2.if逻辑控制器&#xff1a; 3.forEach控制器&#xff1a; 4.循环控制器&#xff1a; 二、关联&#xff1a; 1.xpath&#xff1a; 2.正则表达式提取器&…

homework 2024.11.10 math 1 - math 6

小学1年级和小学6年级数学图形结合&#xff0c;以及习惯养成&#xff0c;过程改进 6年级数学&#xff1a; 一年级数学&#xff1a;

【Linux 31】网络层协议 - IP

文章目录 &#x1f308; 一、IP 协议的基本概念⭐ 1. TCP IP 能保证数据的可靠传输⭐ 2. 如何理解 IP地址⭐ 3. 路由选择⭐ 4. 主机 & 路由器 & 节点 &#x1f308; 二、IP 协议的报头格式⭐ 1. IP 协议的报头格式⭐ 2. 如何将 IP 报头和有效载荷分离⭐ 3. 如何将有效…

Mac中安装OhMyZsh

Mac中安装OhMyZsh 文章目录 Mac中安装OhMyZsh一、Homebrew二、OhMyZsh1、Oh-My-Zsh配置1.1&#xff1a;主题配置1.2&#xff1a;插件配置&#xff08;语法高亮和自动提示&#xff09;1、zsh-autosuggestions&#xff08;需下载安装&#xff09;&#xff1a;高亮显示所有支持的命…

7、computed计算属性使用

代码 Student.vue <template> <div><h2>computed计算属性使用</h2><input type"text" v-model"name"/><br/><input type"text" v-model"sex"/><br/>完整信息&#xff1a;{{info}}&…

SystemVerilog学习笔记(三):结构体与联合体

结构体 结构包含具有不同大小的不同数据类型&#xff0c;这些数据类型分组在一个结构体名称下。默认情况下&#xff0c;结构体最初是未压缩的形式&#xff0c;但可以使用“packed”关键字将其转换为压缩结构。 结构与普通数组不同&#xff0c;因为数组仅使用相同类型和大小的…

无人飞手培训机构大量新增,如何选择好的培训机构?

随着无人机技术的普及和应用领域的拓展&#xff0c;无人机飞手培训机构确实在大量新增。为了选择一家好的培训机构&#xff0c;可以从以下几个方面进行考量&#xff1a; 一、培训资质 官方认证&#xff1a;选择具备中国航空器拥有者及驾驶员协会&#xff08;AOPA-China&#x…

Wi-Fi背后的工作原理与技术发展历程介绍【无线通信小百科】

1个视频说清楚WIFI&#xff1a;频段/历程/技术参数/常用模块 智能手机拥有率越来越高的今天&#xff0c;大家已经习惯了通过无线网络上网的方式。除了在外面需要用手机流量&#xff0c;我们通常在家里或者机场&#xff0c;商场都可以通过Wi-Fi连接上网。本期文章将为大家介绍Wi…

入门车载以太网(4) -- 传输层(TCP\UDP)

目录 1.ECU通信方式的变化 2.传输层概述 2.1 UDP 2.2 TCP 3. TCP和ISO 15765-2 1.ECU通信方式的变化 我们先回顾下两种通信方式&#xff1a;Signal-Based Messaging、Service-Based Messaging。 Signal-Based Messaging 基于信号的通信方式&#xff0c;例如CAN通信&…

软件测试第二篇软件测试技术

第五章单元测试和集成测试的技术 单元静态测试主要由开发人员完成。 标准&#xff1a;规定什么能做&#xff0c;什么不能做。 规范&#xff1a;建议你要怎么做。 5.1.2 代码评审 代码评审是一种发现代码缺陷的另一种测试方法。 代码审查的最佳实践&#xff1a; 创建代码审…

w035基于web的学科竞赛管理

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0…

导航系统非完整性约束汽车运动公约

Back to FDISYSTEMS Knowledge Base 惯性&导航传感器 导航系统&运动约束 数学基础 & 约定 参考坐标系载体 & 传感器坐标系方向/旋转表示非线性卡尔曼滤波器SPKF汽车运动公约船舶运动公约 惯性传感器安装 惯性传感器运行 技术洞察 Knowledge Base /数学基础…

Centos8 安装 JDK / Python / MySQL / Redis / Nginx

安装 JDK 华为镜像 JDK 下载地址&#xff1a;https://repo.huaweicloud.com:8443/artifactory/java-local/jdk/ 这里安装 JDK8 为例&#xff1a; # 这里直接通过 wget 下载 wget https://repo.huaweicloud.com:8443/artifactory/java-local/jdk/8u202-b08/jdk-8u202-linux-x…

【Qt-ROS开发】使用 Qt Creator 构建和编译含 ROS 库的 Qt 项目

【Qt-ROS】使用 Qt Creator 构建和编译含 ROS 库的项目 网上大多数办法是在 Qt creator中安装 ros_qtc_plugin 插件&#xff0c;项目以 ROS1 工作空间的形式构建&#xff0c;还是使用 catkin 来构建整个项目。但是这种方式局限很大&#xff0c;导入 Qt 的组件反而变得很麻烦&a…