跳转至

链表 Linked List

有单链表(singly linked list)和双向链表(doubly linked list),主要考察单向链表,双向链表一般比较简单。

基本操作

  1. 写链表class(ADT):单链表、双向链表、长度、尾节点等特性都会写。
  2. 虚拟头(dummy head):可以保证能找到链表头在哪,防止原链表头删了等,遍历的时候也不用特殊处理链表头,方便
  3. 添加任意index的node:要注意怎么添加链表头和尾(index = 0)
  4. 删除任意index的node:要注意怎么删除链表头
  5. 反转链表

标准迭代答案,就用while node:和一个newHead(或者叫lastprev),不要用while node.next:!\ 记住上面是2行,while里面是4行!

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
   def reverseList(self, head: ListNode) -> ListNode:
       # 迭代
       newHead = None
       node = head
       while node:
           next = node.next
           node.next = newHead
           newHead = node
           node = next
       return newHead

标准递归答案,有点难想,多做加记忆!

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        # 递归
        if not head or not head.next:
            return head
        newHead = self.reverseList(head.next)
        head.next.next = head
        head.next = None
        return newHead

双指针

单链表只能是同向指针,但是灵活运用多个快慢指针,有奇效。

  1. 在不知道总长的情况下,找倒数第i个元素、找中间等
  2. 链表找环入口
  3. 找两个链表相交点

LeetCode

# 题名 难度 标签 备注
707 设计链表 Design Linked List 中等 链表 细节总是写不对,要多注意和练习。单双链表都要会。
141 环形链表 Linked List Cycle 简单 双指针 可以用快慢指针,但直接标记已扫过的也行。
142 环形链表二 Linked List II 中等 双指针 不允许该原来的链表,不用哈希表的话只能用快慢指针了。从零做的话是需要数学推导计算怎么找环的入口的。但从做题角度,可以记住这个套路,考官要求推的时候记得推就行。
160 相交链表 Intersection of Two Linked Lists 中等 双指针 双指针,也可以记忆。两个同速指针同时分别从两个链表头出发,不相交则末尾不等,否则相交。若相交,走完了去走另一个链表,相交时路程等长。
19 删除链表的倒数第 N 个结点 Remove Nth Node From End of List 中等 双指针 两个指针差n。
206 反转链表 Reverse Linked List 简单 链表 基本操作,要熟练。
203 移除链表元素 Remove Linked List Element 简单 链表 基本操作,要熟练。
328 奇偶链表 Odd Even Linked List 中等 链表 应该算简单,基本操作。
234 回文链表 Palindrome ([ˈpalɪndrəʊm]) Linked List 中等 链表 找中间、反转尾部。
21 合并两个有序链表 Merge Two Sorted Lists 简单 链表 基本操作。
61 Rotate List 中等 链表 应该算简单题,只是取余数然后拼接数组。虽然是两个指针,但并不依赖双指针解题,只是方便操作。