力扣之链表专题

1. (LeetCode-21)合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

思路: 双指针或者递归,既然是有序链表排序,那么我们可以制定一个l1指向第一个链表 l2指向第二个链表,再建立一个结果链表和一个指针p,然后比较两个链表的大小,比较一个数值,就挂在p的后面,因此无外乎几种情况1. l1为null,直接返回l2;2.l2为null,直接返回l1,3.链表有值进行比较 3.1.l1先完 直接将l2剩余的挂在p后面 l2先完,将l1挂在p后面,如图所示

 代码实现如下:

class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {if(list1 == null ) return list2;if(list2 == null ) return list1;ListNode head = new ListNode(0);   // 创建一个空NodeListNode p = head;  // 指针p指向头节点while (list1 != null && list2 != null ) {if(list1.val <= list2.val ) {p.next = list1;list1 = list1.next;}else {p.next = list2;list2 = list2.next;}p = p.next;}if (list1 != null ) {p.next = list1;}if(list2 != null ) {p.next = list2;}return head.next;    // 返回链表}
}

递归的思路就是每移掉一个接口,就是相当于两个新的有序链表重新排序,递归结束条件就是某一个链表为null,可以自行实现 ,其算法复杂度也是O(m+n)

2. (LeetCode-83)删除排序链表中的重复元素

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

示例 1:

输入:head = [1,1,2]
输出:[1,2]

示例 2:

输入:head = [1,1,2,3,3]
输出:[1,2,3]

思路:  指针,将当前节点的val与next节点的val进行比较,若相等,则当前节点的next直接跳到next.next。代码实现

class Solution {public ListNode deleteDuplicates(ListNode head) {if(head == null ) {return head;}ListNode cur = head;while (cur.next != null ) {if(cur.val == cur.next.val) {cur.next = cur.next.next;}else {cur = cur.next;}}return head;}
}

3. (LeetCode-141)环形链表

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环

思路:  快慢指针,快指针一次挪两下,慢指针一次挪一下,如果是个环的话,快慢指针就一定会相遇。

public class Solution {public boolean hasCycle(ListNode head) {if(head == null ) return false;ListNode fast = head;ListNode slow = head;while (fast.next != null && fast.next.next != null ) {slow = slow.next;fast = fast.next.next;if(slow == fast) {return true;}}return false;}
}

4. (LeetCode-142)环形链表II

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

 思路: 同样快慢指针,那么快慢指针相遇的地方肯定是环中的某个地方,然后此时把慢指针放到头节点,与快指针同时移动同样的步长1,这样,再次相遇的地方就是环开始的地方,代码如下:

public class Solution {public ListNode detectCycle(ListNode head) {if(head == null )  return null;ListNode fast = head;ListNode slow = head;boolean loopExists = false;while(fast.next != null && fast.next.next != null ) {fast = fast.next.next;slow = slow.next;if (fast == slow){  //在环中相遇了表示有环loopExists = true;break;}   }if(loopExists) {ListNode slowStr = head;while (slowStr  != fast ) {slowStr = slowStr.next;fast = fast.next;}return slowStr;}return null;}
}

5.(LeetCode-160) 相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

自定义评测:

评测系统 的输入如下(你设计的程序 不适用 此输入):

  • intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0
  • listA - 第一个链表
  • listB - 第二个链表
  • skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数
  • skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数

评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA 和 headB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案 。

 

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
— 请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。

 

示例 2:

输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [1,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 。

进阶:你能否设计一个时间复杂度 O(m + n) 、仅用 O(1) 内存的解决方案?

 思路: 双指针,A B指针同时遍历指向headA和headB,当遍历完一遍之后,重新换一次指向,这样就可以消除a b之间的链表的长度差,当再次相遇的时候,就是两个链表的交叉点了,代码如下:

public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headA == null || headB == null ) return null;ListNode pA = headA;ListNode pB = headB;while (pA != pB ) {pA = pA == null ? headB : pA.next; pB = pB == null ? headA : pB.next; }return pA;}
}

6.(LeetCode-206)反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

 思路: 要进行链表的反转,可以假定一个preNode,然后链表向后遍历,每遍历一个节点,它的next指向指向preNode,preNode向后移动一下,代码如下:

class Solution {public ListNode reverseList(ListNode head) {ListNode preNode = null;ListNode cur = head;while (cur != null ) {ListNode next = cur.next;cur.next = preNode;preNode = cur;cur = next;}return preNode;}
}

7.(LeetCode-234)回文链表

给你一个单链表的头节点 head ,请你判断该链表是否为

回文链表

。如果是,返回  true ;否则,返回  false 。

示例 1:

输入:head = [1,2,2,1]
输出:true

示例 2:

输入:head = [1,2]
输出:false

提示:

  • 链表中节点数目在范围[1, 105] 内
  • 0 <= Node.val <= 9

进阶:你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

思路: 快慢指针,因为回文链表是对称型的,因此快指针移动到末尾的时候,慢节点会移动到链表的中间,此时将慢节点之后的链表进行反转 然后依次与原链表比较,直到慢链表结束,如果有值不相等,则一定不是回文链表

 代码如下:

class Solution {public boolean isPalindrome(ListNode head) {if (head == null ) return false;ListNode fast = head;ListNode slow = head;while (fast != null && fast.next != null) {fast = fast.next.next;slow = slow.next;}if (fast != null ) {slow = slow.next;}slow = converse(slow);fast = head;while (slow != null ) {if(fast.val != slow.val ) {return false;}fast = fast.next;slow = slow.next;}return true;}private ListNode converse(ListNode head) {ListNode preNode = null;ListNode cur = head;while (cur != null ) {ListNode next = cur.next;cur.next = preNode;preNode = cur;cur = next;}return preNode;}
}

8.(LeetCode-876)链表的中间结点

给你单链表的头结点 head ,请你找出并返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

示例 1:

输入:head = [1,2,3,4,5]
输出:[3,4,5]
解释:链表只有一个中间结点,值为 3 。

示例 2:

输入:head = [1,2,3,4,5,6]
输出:[4,5,6]
解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。

 思路: 快慢指针,因为快指针是慢指针步幅的两倍, 因此快指针到达末尾的时候,慢指针刚好到达中间值,代码如下:

class Solution {public ListNode middleNode(ListNode head) {if (head == null ) return null;ListNode fast = head;ListNode slow = head;while (fast != null && fast.next != null ) {fast = fast.next.next;slow = slow.next;}return slow;}
}

9. 总结

        力扣的链表专题,主要就是快慢指针的灵活运用,要学会合理的构建指针,构建空链表,以存储不同的链表节点,灵活运用链表的指向关系即可。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务架构-微服务实施

目录 一、概述 二、微服务拆分 2.1 概述 2.2 拆分原则 2.3 拆分方法 2.3.1 以数据为维度进行拆分 2.3.2 按照使用场景拆分 2.3.3 重要和非重要的拆分 2.3.4 变和不变的拆分 三、微服务通信 3.1 概述 3.2 微服务通信方式选择 3.3 微服务编排 3.4 API接口设计 3.5 …

「计网」网络初识

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;计网 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 网络初识 &#x1f349;IP 地址 & 端口号&#x1f349;网络协议&#x1f34c;TCP/IP 网络协议 &#x1f349;封装和分用&#x1f349…

乡村振兴与乡村旅游创新:创新乡村旅游产品,提升旅游服务水平,打造特色乡村旅游品牌,助力美丽乡村建设

目录 一、引言 二、乡村旅游产品的创新 &#xff08;一&#xff09;挖掘乡村特色资源 &#xff08;二&#xff09;注重产品体验性 &#xff08;三&#xff09;创新旅游产品形态 三、旅游服务水平的提升 &#xff08;一&#xff09;加强基础设施建设 &#xff08;二&…

如何上传模型素材创建3D漫游作品?

一、进入3D空间漫游互动工具编辑器 进入720云官网-点击“开始创作”-选择3D空间漫游-进入到作品创建页面。 二、上传模型及素材&#xff0c;创建生成3D空间漫游模型 1.创建3D空间作品&#xff1a;您可以选择新建空白作品或使用720云提供的预设空间模板&#xff0c;本篇主要介绍…

[手游] Florence逝去的爱弗洛伦斯

图片处理工具箱Hummingbird : Hummingbird使用智能压缩技术来减少文件的大小&#xff0c;支持&#xff1a;jpg、png、webp、svg、gif、gif、css、js、html、mp4、mov&#xff0c;可以设置压缩的同时等比例缩放图片或视频的尺寸。可以拖放文件夹压缩&#xff0c;一次最多可处理1…

【vue3 + Echarts 】中国地图省市区下钻,并返回上级

实现效果如果&#xff1a; echarts版本&#xff1a; 地图数据来源&#xff1a;阿里云数据可视化平台 代码 <template><div class"mapWrapper"><a-button type"primary" click"goBack">返回上级</a-button><div…

一步步实现知乎热榜采集:Scala与Sttp库的应用

背景 在大数据时代&#xff0c;网络爬虫技术发挥着不可或缺的作用。它不仅能够帮助我们快速地获取互联网上的信息&#xff0c;还能处理和分析这些数据&#xff0c;为我们提供深刻的洞察。知乎&#xff0c;作为中国领先的问答社区&#xff0c;汇聚了各行各业的专家和广大用户的…

【LeetCode刷题】二分查找:寻找旋转排序数组中的最小值、点名

【LeetCode刷题】Day 14 题目1&#xff1a;153.寻找旋转排序数组中的最小值思路分析&#xff1a;思路1&#xff1a;二分查找&#xff1a;以A为参照思路2&#xff1a;二分查找&#xff0c;以D为参照 题目2&#xff1a;LCR 173.点名思路分析&#xff1a;思路1&#xff1a;遍历查找…

(2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X

Lumina-T2X: Transforming Text into Any Modality, Resolution, and Duration via Flow-based Large Diffusion Transformers 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 …

使用Streamlit和MistralAI创建AI聊天机器人应用

大家好&#xff0c;创建交互式和用户友好型的应用程序通常需要复杂的框架和耗时的开发过程。Streamlit是一个Python库&#xff0c;它简化了以数据为重点的网络应用程序的创建过程&#xff0c;使开发人员和数据科学家能够快速将他们的想法转化为交互式仪表盘和原型。本文将介绍使…

『 Linux 』文件系统

文章目录 磁盘构造磁盘抽象化 磁盘的寻址方式磁盘控制器磁盘数据传输文件系统Inode数据块(Data Blocks)超级块(SuperBlock)块组描述符(Group Descriptor) 磁盘构造 磁盘内部构造由磁头臂,磁头,主轴,盘片,盘面,磁道,柱面,扇区构成; 磁头臂&#xff1a;控制磁头的移动,可以精确地…

vs2019 QT UI 添加新成员或者控件代码不提示问题解决方法

右键点击头文件&#xff0c;添加ui的头文件 添加现有项 找到uic目录的头文件 打开ui,QtWidgetsApplication2.ui,进行测试 修改一个名字&#xff1a; 重点&#xff1a; 设置一个布局&#xff1a; 点击生成解决方案&#xff1a; 以后每次添加控件后&#xff0c;记得点击保存 这样…

flink 作业报日志类冲突的解决方案

文章目录 背景思考初步解决方案深入思考下终极解决方案总结 背景 实时作业在页面提交任务后&#xff0c;报NoSuchMethodException 方法&#xff0c;看了下是关于log4j的&#xff0c;首先是作业升级了很多依赖的版本&#xff0c;其次flink 也升级 到了1.19版本 思考 打的Jar有…

CSS选择器的常见用法

大家好&#xff0c;本期博客整理了前端语言 CSS 中选择器的入门级常见用法&#xff0c;希望能对大家有所帮助 CSS 选择器的主要功能就是选中⻚⾯指定的标签元素&#xff0c;选中了元素&#xff0c;才可以设置元素的属性。 那么&#xff0c;css选择器有哪几种呢&#xff1f; 以…

全面理解渗透测试

揭秘网络安全的秘密武器&#xff1a;全面理解渗透测试 在数字化时代&#xff0c;网络安全已成为人们关注的焦点。网络攻击和数据泄露事件频发&#xff0c;给个人、企业和国家带来了巨大的损失。为了应对这一挑战&#xff0c;渗透测试作为一种重要的网络安全评估手段&#xff0…

Docker-----emqx部署

emqx通过Docker容器化部署流程 1.创建持久化挂载目录 mkdir -p /home/emqx/etc ------挂载emqx的配置文件目录 mkdir -p /home/emqx/data ------挂载emqx的存储目录 mkdir -p /home/emqx/log ------挂载emqx的日志目录 [root home]# mkdir -p /home/emqx/etc [root home]# mkd…

【Redis】 使用Java操作Redis的客户端

文章目录 &#x1f343;前言&#x1f334;项目的创建&#x1f38b;引入依赖&#x1f333;配置端⼝转发&#x1f332;更改 Redis 配置文件&#x1f384;连接 Redis Server⭕总结 &#x1f343;前言 我们使用 Java 操作 Redis 客户端时我们需要进行以下操作。 注意&#xff1a;J…

Linux上部署和安装MinIO

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法&#xff0c;大数据&#xff0c;深度学习 &#x1f492; 公众号…

2024年6月1日 (周六) 叶子游戏新闻

Embracer探讨单机游戏大作涨价超过70美元的可能性在Embracer集团等待公布新公司名称的同时&#xff0c;他们对游戏大作的价格上涨做出了评论。几年来&#xff0c;游戏大作的价格已经达到了70美元的门槛。Embracer集团的CEO Lars Wingefors在采访中表示&#xff0c;电子游戏行业…

vulnhub靶场之FunBox-10

一.环境搭建 1.靶场描述 As always, its a very easy box for beginners. This works better on VitualBox rather than VMware 2.靶场下载 Funbox: Under Construction! ~ VulnHub 3.靶场启动 靶场IP地址我们不知道&#xff0c;但是网段我们知道是192.168.2.0/24 二.信息…