1. 链表算法实战:LeetCode高频题目深度解析
链表作为数据结构中的基础类型,在算法面试中出现的频率极高。最近在准备技术面试时,我系统梳理了LeetCode上最常考的链表类题目,发现其中10道题目几乎覆盖了所有链表操作的考察点。今天就把这些题目的解题思路、代码实现和避坑经验完整分享给大家。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 链表基础与核心操作
2.1 链表结构特性
链表通过指针将零散的内存块串联起来,每个节点包含数据域和指针域。与数组相比,链表在插入/删除操作上具有O(1)时间复杂度优势,但随机访问效率较低。
python复制class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
2.2 必须掌握的六大核心操作
- 遍历操作:while循环配合指针移动
- 节点插入:注意指针修改顺序
- 节点删除:需要维护前驱指针
- 反转操作:经典的三指针法
- 快慢指针:解决环检测等问题
- 递归处理:简化复杂操作逻辑
3. 高频题目详解与实现
3.1 反转链表(LeetCode 206)
最基础的链表操作题,考察指针操作能力。
迭代解法:
python复制def reverseList(head):
prev = None
curr = head
while curr:
next_temp = curr.next
curr.next = prev
prev = curr
curr = next_temp
return prev
递归解法:
python复制def reverseList(head):
if not head or not head.next:
return head
p = reverseList(head.next)
head.next.next = head
head.next = None
return p
注意:递归解法虽然简洁,但空间复杂度为O(n),面试时建议先给出迭代解法。
3.2 环形链表检测(LeetCode 141/142)
经典的快慢指针应用场景。
python复制def hasCycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
进阶问题(142题)需要找到环的入口点:
python复制def detectCycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
break
else:
return None
ptr = head
while ptr != slow:
ptr = ptr.next
slow = slow.next
return ptr
3.3 相交链表(LeetCode 160)
巧妙利用双指针遍历路径相同的特性。
python复制def getIntersectionNode(headA, headB):
pA, pB = headA, headB
while pA != pB:
pA = pA.next if pA else headB
pB = pB.next if pB else headA
return pA
4. 复杂链表问题解析
4.1 随机链表复制(LeetCode 138)
需要在O(n)时间内完成含随机指针的链表深拷贝。
三步解法:
- 在原节点后插入拷贝节点
- 设置random指针
- 分离两个链表
python复制def copyRandomList(head):
if not head:
return None
# 第一步:插入新节点
curr = head
while curr:
new_node = Node(curr.val)
new_node.next = curr.next
curr.next = new_node
curr = new_node.next
# 第二步:设置random指针
curr = head
while curr:
if curr.random:
curr.next.random = curr.random.next
curr = curr.next.next
# 第三步:分离链表
old = head
new = head.next
new_head = head.next
while old:
old.next = old.next.next
new.next = new.next.next if new.next else None
old = old.next
new = new.next
return new_head
4.2 排序链表(LeetCode 148)
要求时间复杂度O(nlogn),空间复杂度O(1)。
归并排序实现:
python复制def sortList(head):
if not head or not head.next:
return head
# 分割链表
slow, fast = head, head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
mid = slow.next
slow.next = None
# 递归排序
left = sortList(head)
right = sortList(mid)
# 合并有序链表
dummy = ListNode(0)
curr = dummy
while left and right:
if left.val < right.val:
curr.next = left
left = left.next
else:
curr.next = right
right = right.next
curr = curr.next
curr.next = left if left else right
return dummy.next
5. 链表操作技巧总结
5.1 虚拟头节点技巧
处理头节点可能被修改的情况时,使用dummy节点可以简化逻辑:
python复制dummy = ListNode(0)
dummy.next = head
# ...处理逻辑...
return dummy.next
5.2 边界条件处理
链表问题需要特别注意:
- 空链表处理
- 单节点链表
- 头节点/尾节点特殊情况
- 指针越界问题
5.3 调试技巧
- 打印链表内容辅助调试:
python复制def printList(head):
while head:
print(head.val, end=" -> ")
head = head.next
print("None")
- 构造测试用例时注意:
- 普通情况
- 空链表
- 单节点链表
- 有环链表
- 相交链表
6. 进阶题目解析
6.1 两数相加(LeetCode 2)
处理链表表示的大数相加问题。
python复制def addTwoNumbers(l1, l2):
dummy = ListNode()
curr = dummy
carry = 0
while l1 or l2 or carry:
sum_val = carry
if l1:
sum_val += l1.val
l1 = l1.next
if l2:
sum_val += l2.val
l2 = l2.next
carry, val = divmod(sum_val, 10)
curr.next = ListNode(val)
curr = curr.next
return dummy.next
6.2 删除倒数第N个节点(LeetCode 19)
快慢指针的经典应用。
python复制def removeNthFromEnd(head, n):
dummy = ListNode(0)
dummy.next = head
fast = slow = dummy
for _ in range(n):
fast = fast.next
while fast.next:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return dummy.next
7. 链表算法面试要点
- 时间复杂度分析必须准确
- 空间复杂度优化要主动说明
- 边界条件处理要全面
- 变量命名要有意义
- 代码可读性要强
- 测试用例要考虑周全
链表问题的解决关键在于指针操作的熟练度。建议每天练习2-3道链表题目,坚持两周就能明显提升解题速度和代码质量。在实际面试中,建议先和面试官确认输入输出要求,再开始编写代码。
