一、问题(含示例)

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

示例 1:

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

示例 2:

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

示例 3:

输入:head = [7,7,7,7], val = 7
输出:[]

二、核心实现思路与代码解析

  1. 核心难点:直接删除头节点时需特殊处理(头节点无前驱),连续多个目标节点也需统一处理。
  2. 解决方案:引入 “虚拟头节点”(dummy),其 next 指向原头节点 head,将 “删除头节点” 与 “删除其他节点” 的逻辑统一。
  3. 关键代码逻辑
    • 创建虚拟头节点:dummy = ListNode(0); dummy.next = head,确保所有节点(包括头节点)都有前驱。
    • 遍历与删除:用 current 指针从 dummy 开始遍历,若 current.next.val == val,则通过 current.next = current.next.next 跳过目标节点(删除);否则 current 后移。
    • 返回结果:dummy.next 即为删除后的新头节点

三、辅助函数的作用与细节

  1. list_to_linkedlist(lst):将普通列表转换为链表,方便手动构造测试用例。

    • 原理:先创建头节点,再用 current 指针依次连接后续节点(current 负责移动连接,head 固定保存头节点引用)。
    • 易错点:若删除 current 直接修改 head,会导致 head 最终指向尾节点,无法返回完整链表(因 head 需固定作为入口)。
  2. linkedlist_to_list(head):将链表转换为普通列表,方便直观查看结果。

    • 原理:遍历链表,将每个节点的值存入列表,最终返回列表。
  3. 辅助函数的定位:提交代码时多余(判题系统直接处理链表),但调试时必不可少(简化链表的创建与结果查看)。

四、Python 底层原理支撑

  1. 变量存储对象引用Python 中变量存储的是对象的内存地址(引用),而非对象本身。
    • 例如 current = head 时,current 与 head 指向同一节点(共享引用)。
    • 修改 current.next 时,实际修改的是共享节点的属性,会同步反映到 head 指向的节点(因此新节点能 “挂在 head 后面”)。
  2. 内存地址表示:如 0x123 是十六进制内存地址(表示十进制 291),仅为简化说明,实际地址更长(32 位系统 8 位十六进制,64 位系统 16 位)。

对应解题代码:

# 定义链表节点类
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def removeElements(head: ListNode, val: int) -> ListNode:
    # 创建虚拟头节点,方便处理头节点被删除的情况
    dummy = ListNode(0)
    dummy.next = head
    
    # 当前指针,初始指向虚拟头节点
    current = dummy
    
    # 遍历链表
    while current.next:
        if current.next.val == val:
            # 找到要删除的节点,跳过该节点
            current.next = current.next.next
        else:
            # 继续遍历下一个节点
            current = current.next
    
    # 返回新的头节点(虚拟头节点的下一个节点)
    return dummy.next

# 辅助函数:将列表转换为链表
def list_to_linkedlist(lst):
    if not lst:
        return None
    head = ListNode(lst[0])
    current = head
    for val in lst[1:]:
        current.next = ListNode(val)
        current = current.next
    return head

# 辅助函数:将链表转换为列表(用于测试)
def linkedlist_to_list(head):
    result = []
    current = head
    while current:
        result.append(current.val)
        current = current.next
    return result

# 测试示例
if __name__ == "__main__":
    # 示例1
    head1 = list_to_linkedlist([1,2,6,3,4,5,6])
    val1 = 6
    result1 = removeElements(head1, val1)
    print(linkedlist_to_list(result1))  # 输出: [1,2,3,4,5]
    
    # 示例2
    head2 = list_to_linkedlist([])
    val2 = 1
    result2 = removeElements(head2, val2)
    print(linkedlist_to_list(result2))  # 输出: []
    
    # 示例3
    head3 = list_to_linkedlist([7,7,7,7])
    val3 = 7
    result3 = removeElements(head3, val3)
    print(linkedlist_to_list(result3))  # 输出: []

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐