链表操作中的指针艺术
链表在面试中常作为考察指针操作和边界处理的经典题型。相比于数组,链表没有随机访问能力,因此很多看似简单的逻辑需要仔细处理节点间的连接关系。今天我们来梳理 LeetCode Hot 100 中关于链表的核心考点,重点攻克反转与排序两大板块。
基础反转:206. 反转链表
这是所有链表反转问题的基石。核心思路是遍历链表,将每个节点的 next 指针指向前一个节点。为了处理头节点的变化,通常需要一个哑节点(dummy)或者临时变量来保存前驱节点。
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
pre = None
cur = head
while cur:
nxt = cur.next
cur.next = pre
pre = cur
cur = nxt
return pre
这里的关键在于 nxt 的暂存。如果直接修改 cur.next,后续就无法继续向后遍历了。通过 pre 和 cur 的双指针推进,我们实现了原地反转,空间复杂度为 O(1)。
区间反转:92. 反转链表 II
当需求变为只反转链表中从第 left 个到第 right 个节点时,我们需要定位到 left-1 的位置,然后对中间段执行类似基础反转的逻辑,最后重新连接前后两部分。
使用哑节点可以简化头节点变化的边界情况。找到 p0(即 left-1 位置的节点),然后进行 k 次指针翻转操作。
class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
dummy = ListNode(0)
dummy.next = head
p0 = dummy
_ (left - ):
p0 = p0.
pre =
cur = p0.
_ (right - left + ):
nxt = cur.
cur. = pre
pre = cur
cur = nxt
p0.. = cur
p0. = pre
dummy.


