数据结构练习题4(链表)
1两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
示例 2:
输入:head = [] 输出:[]
示例 3:
输入:head = [1] 输出:[1]
提示:
- 链表中节点的数目在范围
[0, 100]
内 0 <= Node.val <= 100
思路:
初始检查:如果链表为空或只有一个节点,直接返回。
创建虚拟头节点:使用一个虚拟头节点 dummy 来简化边界情况的处理。
循环交换节点对:在链表中继续交换每一对节点,直到没有更多的节点对(cur->next && cur->next->next 都不为空时)可以交换。开始时cur为与虚拟头结点位置
步骤一:cur->next 指向第二个节点。
步骤二:第二个节点的 next 指向第一个节点。
步骤三:第一个节点的 next 指向第三个节点。
移动到下一对节点的前一个节点:将 cur 移动到下一对节点的前一个节点。
代码:
struct ListNode* swapPairs(struct ListNode* head) {// 如果链表为空或只有一个节点,直接返回if (!head || !head->next) return head;struct ListNode dummy; // 创建一个虚拟头节点dummy.next = head;struct ListNode* cur = &dummy;while (cur->next && cur->next->next) {struct ListNode* tmp = cur->next; // 保存第一个节点struct ListNode* tmp1 = cur->next->next->next; // 保存第二个节点的下一个节点cur->next = cur->next->next; // 步骤一:cur->next 指向第二个节点cur->next->next = tmp; // 步骤二:第二个节点的 next 指向第一个节点cur->next->next->next = tmp1; // 步骤三:第一个节点的 next 指向第三个节点cur = cur->next->next; // 移动到下一对节点的前一个节点}return dummy.next; // 返回新的头节点
}
2删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1 输出:[]
示例 3:
输入:head = [1,2], n = 1 输出:[1]
提示:
- 链表中结点的数目为
sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
思路:
- 创建虚拟头节点:使用
malloc
分配内存并创建一个虚拟头节点dummy
,其val
为 0,next
指向实际的头节点head
。 - 初始化快慢指针:
fast
和slow
都指向虚拟头节点。 - 快指针先移动 n 步:通过循环,让
fast
指针先移动n
步。 - 快指针再移动一步:因为需要让slow指向删除节点的上一个节点
- 同时移动快慢指针:继续移动
fast
和slow
指针,直到fast
指针到达链表末尾。此时,slow
指针指向的节点就是要删除的节点的前一个节点。 - 删除节点:将
slow
的next
指向slow->next->next
,从而删除目标节点。 - 更新头节点:将
head
更新为dummy->next
。 - 释放虚拟头节点:使用
free
释放虚拟头节点的内存空间。 - 返回头节点:返回更新后的头节点
head
。
代码:
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {// 创建一个虚拟头节点,并初始化其值为0,next指向实际的头节点struct ListNode* dummy = malloc(sizeof(struct ListNode));dummy->val = 0;dummy->next = head;// 初始化快慢指针,都指向虚拟头节点struct ListNode* fast = dummy;struct ListNode* slow = dummy;// 快指针先向前移动n步for (int i = 0; i < n; i++) {fast = fast->next;}// fast再提前走一步,因为需要让slow指向删除节点的上一个节点fast = fast->next;// 快慢指针同时移动,直到快指针到达链表末尾while (fast) {fast = fast->next;slow = slow->next;}// 删除慢指针的下一个节点(即倒数第n个节点)slow->next = slow->next->next;// 更新头节点(dummy是虚拟头节点,删除操作不会影响head)head = dummy->next;// 释放虚拟头节点的内存(注意:这里应该释放dummy,而不是释放dummy->next,因为dummy->next是实际的链表节点)free(dummy);// 返回更新后的头节点return head;
}
3链表相交
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
。
图示两个链表在节点 c1
开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Intersected at '8' 解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。 在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 输出:Intersected at '2' 解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。 在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
示例 3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 输出:null 解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。 由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 这两个链表不相交,因此返回 null 。
提示:
listA
中节点数目为m
listB
中节点数目为n
0 <= m, n <= 3 * 104
1 <= Node.val <= 105
0 <= skipA <= m
0 <= skipB <= n
- 如果
listA
和listB
没有交点,intersectVal
为0
- 如果
listA
和listB
有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]
思路:
- 初始化变量:定义
longList
和shortList
用于存储长链表和短链表的头节点,lenA
和lenB
用于存储两个链表的长度,gap
用于存储长度差。 - 计算链表长度:通过遍历链表
headA
和headB
,分别计算它们的长度lenA
和lenB
。 - 确定长链表和短链表:通过比较
lenA
和lenB
,确定哪个是长链表,哪个是短链表,并计算长度差gap
。 - 尾部对齐:将长链表
longList
移动gap
步,使得两个链表的尾部对齐。 - 同时移动并检查交点:同时移动
longList
和shortList
,检查是否有相同的节点。如果找到相同的节点,则返回该节点(即交点)。 - 返回结果:如果没有找到交点,则返回
NULL
。
代码:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode *longList = NULL, *shortList = NULL;int lenA = 0, lenB = 0, gap = 0;// 求出两个链表的长度shortList = headA;while (shortList) {lenA++;shortList = shortList->next;}shortList = headB;while (shortList) {lenB++;shortList = shortList->next;}// 确定长链表和短链表,并计算长度差if (lenA > lenB) {longList = headA;shortList = headB;gap = lenA - lenB;} else {longList = headB;shortList = headA;gap = lenB - lenA;}// 将长链表和短链表的尾部对齐while (gap--) {longList = longList->next;}// 同时移动长链表和短链表,检查是否有相同的节点while (longList) {if (longList == shortList) return longList; // 找到交点longList = longList->next;shortList = shortList->next;}// 没有找到交点return NULL;
}
相关文章:

数据结构练习题4(链表)
1两两交换链表中的节点 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 输入:head [1,2,3,4]…...

【前端】如何制作自己的网站(7)
以下内容接上文。 结合图片的超链接 将img元素作为内容,放在a元素中。即可为图片添加一个超链接。 例如右边的代码,点击头像就会打开“aboutme.html“。 点击右边的图片试试~ 两个非文本元素——图片与超链接。 从现在开始࿰…...

《数字图像处理基础》学习02-BMP位图文件
目录 一,BMP文件组成 二,使用ultra edit软件查看图像结构 1,ultra edit软件的下载和安装 2,ultra edit打开图像 三,使用matlab显示RGB图像 在之前的文章学习到,计算机只能处理数字图像,因…...

车辆管理系统设计与SpringBoot技术融合
3系统分析 3.1可行性分析 通过对本车辆管理系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本车辆管理系统采用Spring Boot框架,JAVA作为开发语…...

常见TCP/IP协议基础——计算机网络
目录 前言常见协议基础常见协议-基于TCP的应用层协议常见协议-基于UDP的应用层协议常见协议-网络层协议习题自测1.邮件发送协议2.接收邮件协议端口3.建立连接4.层次对应关系5.FTP服务器端口 前言 本笔记为备考软件设计师时的重点知识点笔记,关于常见TCP/IP协议基础…...

SVM支持向量机python实现
支持向量机(Support Vector Machine, SVM)是一种强大的监督学习算法,主要用于分类和回归任务。SVM的核心思想是找到一个最优的超平面,使得不同类别的数据点能够被尽可能清晰地分开,并且这个超平面与最近的数据点之间有…...

linux查看系统类型
要确定系统是 Ubuntu 还是 CentOS,可以通过查看系统的发行版信息来判断。以下是几种常见的方法: 方法一:使用 cat 命令查看 /etc/os-release 文件 这个文件包含了系统的详细信息,包括发行版名称和版本号。 cat /etc/os-release…...

SpringSecurity 捕获自定义JWT过滤器抛出的异常
自定义过滤器如下: /*** jwt过滤器,验证令牌是否合法** author 朱铭健*/ Slf4j public class JwtAuthenticationFilter extends OncePerRequestFilter {Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse resp…...

中小型企业网络的设计与实现
资料下载中小型企业网络的设计与实现论文资源-CSDN文库 摘 要 本文规划的是一个公司的网络搭建,网络设计包括了多个部门的网络架构,每个部门通过VLAN进行隔离,确保了网络的安全性和高效。 华为企业网络模拟平台(ENSP)…...

小马识途海外媒体推广有何优势?
互联网让地球变得像一个村子一样,信息可以瞬间变得人尽皆知,商品和服务也同样习惯了跨国合作。中国不少物美价廉的产品在世界各地都很受欢迎,国内小资群体对国外的服饰和美妆更是偏爱有加。小马识途营销顾问认为,中国品牌不出走国…...

Spring Boot知识管理:跨平台集成方案
4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示: 图4-1系统工作原理…...

逆向工程基本流程
1 逆向的基本流程 1获取目标app (官网,豌豆荚),尽量不要去华为应用市场,小米应用市场下载–多渠道打包,安装到手机上 2使用抓包工具 抓包分析(charles,fiddler…) 3使用反编译工具 (JADX,JD-GUI。。),把apk反编译成java代码,分析java代码,定位代码位置 4 使用动态分…...

target_include_directories是如何组织头文件的?
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 这条 CMake 命令用于指定编译目标(在此例中为 mylib 静态库)的头文件搜索路径。具体来说,这条命令的作用包括以下几个方面: 1. 添加包含目录 mylib&…...

【Flutter】Dart:运算符
在 Dart 中,运算符是非常重要的组成部分,它们可以对变量和常量进行多种运算操作。理解和掌握 Dart 中的各种运算符不仅可以帮助你编写更加高效、简洁的代码,还能更好地理解其背后的逻辑和设计。本文将深入探讨 Dart 中的运算符,包…...

ChatGPT01-preivew体验报告:内置思维链和多个llm组合出的COT有啥区别呢?丹田与练气+中学生物理奥赛题测试,名不虚传还是名副其实?
一个月前,o1发布的时候,我写了篇文章介绍 逻辑推理能力堪比博士生,OpenAI发布全新AI模型系列: o1 - 大模型或许进入新阶段,还翻译了官方的介绍 解密OpenAI o1是如何让LLMs获得逻辑推理能力的 - CoT * RL,也…...

《云计算网络技术与应用》实训6-1:配置KVM虚拟机使用NAT网络
任务1、计算节点基础环境准备 1. 使用VMware安装CentOS 7虚拟机,安装时记得开启CPU虚拟化,命名为“KVMC6”。 2. (网卡配置和之前的一样,都用100网段)网关设置为192.168.100.1,地址段为192.168.100.10-25…...

【Unity新闻】Unity 6 正式版发布
Unity CEO Matt Bromberg 在今天自豪地宣布,Unity 6 正式发布!作为迄今为止最强大和稳定的版本,Unity 6 为游戏和应用开发者提供了大量的新功能和工具,帮助他们加速开发并提升性能。 本次正式版是6.0000.0.23f1(LTS&a…...

基于语音识别的停车共享小程序(lw+演示+源码+运行)
目 录 1 绪论1 1.1 课题研究背景1 1.2 研究现状1 1.3 论文结构安排1 2 系统关键技术2 2.1 微信小程序2 2.2 微信Web开发者工具2 2.3 JavaScript简介2 2.4 微信小程序API接口2 2.5 MYSQL数据库2 3 系统分析1 3.1 可行性分析1 3.1.1 技术可行性1 3.1.2 经济可行性1…...

编程考古-计算机发展(上)
计算机/器现在是我们日常生活中的重要工具,它的发展历程见证了人类数学计算能力的不断提升。 什么是计算 计算的本质在于基于规则对符号串进行变换。简言之,从一个初始的符号串(输入)出发,依据既定的法则逐步改变这个…...

pc轨迹回放制作
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:pc轨迹回放制作 主要内容:制作车辆轨迹操作页,包括查询条件、动态轨迹回放、车辆轨迹详情表单等 应用场景:车辆…...

无向图中的一些问题与处理(上接无向图知识简记)
一、有向图中的排序与调度 1、深度优先搜索的排序 使用深度优先搜索对图中顶点进行排序,根据数据结构性质与递归保存顺序,有以下三种排列顺序 (1) 前序:在递归调用之前将顶点加入队列。 (2)后…...

AIGC助力小学生编程梦:C++入门不再难!
文章目录 一、AIGC时代下的编程教育新趋势二、小学生C入门趣味编程的意义三、小学生C入门趣味编程的实践策略四、面临的挑战与应对策略五、AIGC技术在小学生C编程中的应用与前景《小学生C趣味编程从入门到精通》编辑推荐内容简介作者简介目录 随着人工智能生成内容(…...

AI开发-三方库-Hugging Face-Pipelines
1 需求 需求1:pipeline支持的任务类型 需求2:推理加速使用CPU还是GPU 需求3:基于pipeline的文本分类示例 需求4:pipeline实现原理 模型使用步骤(Raw text -》Input IDs -》Logits -》Predictions)&…...

【Python网络编程】学习Socket编程,打造网络应用!
【Python网络编程】学习Socket编程,打造网络应用! 网络编程是现代计算机科学中的重要一环,几乎所有的应用都依赖网络传输数据。无论是创建简单的客户端-服务器模型,还是构建复杂的网络应用,Socket 编程都是关键的技术…...

docker (desktopcompose) download
docker docker-compose download 百度网盘获取离线包链接release-notes 参考dockerdocker-composewlspowershell...

即时通讯:单聊消息逻辑
在线消息(对方在线) 1.client发送消息到msg_server 2.msg_server判断消息有效性,每秒发送的消息不能超过限制,无误后转发给db_server 3.db_server判断为单聊 查找对应的会话,不存在则创建两个会话(双方…...

Libevent源码剖析之reactor
1 简介 reactor 是一种事件驱动的并发处理模式,常用于网络服务器和事件循环系统中。它主要的功能是通过单线程或者多线程处理I/O操作,避免阻塞,并且能够高效处理大量并发的事件。 one loop per thread or process,以下摘自 reacto…...

分享一套SpringBoot+Vue民宿(预约)系统
大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue民宿(预约)系统,分享下嘿嘿。 项目介绍 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,…...

Linux——应用软件的生命周期
功能开发测试: 功能性测试 对应开发框架的测试用例代码的漏洞扫描 Web服务器版本应用开发语言的依赖关系和版本信息是否会造成类似内存泄露等影响系统性能的问题压力测试应用的部署 获取应用代码以及应用静态文件的代码包将安装包中的文件按照服务器配置的架构&…...

【Linux】exec系列函数详细介绍
首先,exec 是 execute (意为:执行) 的缩写。 exec系列函数 各个“后缀”的意思: l 为 list 可变参数列表、v 为 vector、p 为 PATH、e 为环境变量数组 envp execl:l 为 list 可变参数列表 原型:int execl(const char *path, cons…...