链表问题总结

64 阅读3分钟

前言

数据结构

ListNode(val value :T,val next :ListNode) // 单向链表
ListNode(val value :T,val next :ListNode,val pre :ListNode) // 双向链表

链表的数据结构注定了无法像数组一样进行随机访问,无法随意获取链表长度,根据偏移量获取节点是链表的痛点。大多数链表问题都基于此展开。对于这类问题,通常采用双指针(重点:快慢指针)或者双向链表解决:

分析

距离偏移问题,追及相遇问题:双指针(重点:快慢指针)

141. 环形链表

追及问题,slow走一步,fast走两步,成环则快指针一定能追上慢指针

为什么选择slow一步,fast两步呢,我认为只是对于在写代码的同时对于链表遍历好控制罢了,假设我们在操场上跑步,无论慢的人跑多慢,快的人跑多快,只要他们速度不一致,那么总会相遇

142. 环形链表 II 相遇问题,具体分析juejin.cn/post/728896…

19. 删除链表的倒数第 N 个结点

偏移问题,快指针比慢指针多走n步,快指针走到末尾时,慢指针在倒数第N个位置

160. 相交链表 姑且可以看作相遇问题,若两个链表相交,那么相交点可以看作相遇点,如果有相遇点c1,那么如果A,B,从距c1相同点以相同速度出发,一定会在c1相遇,所以只需分别遍历A,B,让长的先走n步,这时短的再出发,相遇则有相交点

image.png

模拟问题

根据要求模拟实现就好,此类问题只需要注意每个问题在模拟时的特殊情况,例如两数相加的进位,两两交换的链表奇偶情况

206. 反转链表

2. 两数相加

24. 两两交换链表中的节点

其他问题

234. 回文链表

常规思路是从中间开始,分别向前,向后遍历元素,相等则为回文

问题1:在于如何找到中点呢,显然快慢指针问题,slow一步,fast两步,不过要注意的是链表长度奇偶情况

问题2 :如何向前遍历,两种方法:方法一,回文问题类似于括号匹配问题,借用这种思想可以用一个stack保存前半段;方法二,利用链表特性,在遍历前半段的同时反转链表

148. 排序链表

使用冒泡等方法可以进行排序,但是时间复杂度为n*n,数组常用的快排因链表无法随机访问而不能使用,为提高排序速度,只能使用归并排序

146. LRU 缓存

最近最少访问,使用链表是因为经常进行删除增加,但链表访问元素只能遍历,但是对于频繁访问缓存,这种时间复杂度是达不到要求的,必须为O(1),

O(1)即哈希,以 value 为 ListNode创建map进行访问

总结:链表 + 哈希

关于我

一个希望友友们能提出建议的代码下毒糕手