算法题(Python)链表篇 | 1.移除链表元素
算法题(Python)链表篇 | 1.移除链表元素
- 题目描述
- 思路
关于链表的理论基础,见卡码网语言基础课(Python) | 13.链表的基础操作I
题目描述
力扣题目链接
给你一个链表的头节点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 4 2 4举例,移除元素4。

如果使用C,C++编程语言的话,不要忘了还需要从内存中删除这两个移除的节点。
当然,如果使用java,python的话,就不用手动管理内存了。
因为单链表的特殊性,只能指向下一个节点,刚刚删除的是链表中的第二个和第四个节点,那如果删除的是头结点该怎么办呢?
这里涉及如下链表操作的两种方式:
- 直接使用原来的链表来进行删除操作
- 设置一个虚拟头结点进行删除操作
第一种操作:直接使用原来的链表来进行移除
移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。
所以头结点如何移除呢,其实只要将头结点向后移动一位就可以,这样就从链表中移除了一个头结点。
依然别忘将原头结点从内存中删掉。
这样移除了一个头结点,是不是发现,在单链表中移除头结点和移除其他节点的操作方式不一样。
第二种操作:设置虚拟头结点
这里给链表添加一个虚拟头结点作为新的头结点,此时要移除这个旧节点元素1。
本题解答代码如下:
- 使用原来的链表进行移除节点操作
时间复杂度O(n)O(n)O(n),空间复杂度O(1)O(1)O(1)。
# 链表节点的类
class Node:# init方法,初始化链表节点属性,包括data和nextdef __init__(self, data):self.data = dataself.next = None# 链表类
class LinkList:# init方法,初始化链表属性,包括头结点和链表长度def __init__(self):self.head_node = Noneself.length = 0# 向链表插入数据的方法def insert(self, data):self.length += 1new_node = Node(data)if self.head_node is None:self.head_node = new_nodereturn self.head_nodecurrent_node = self.head_nodewhile current_node.next is not None:current_node = current_node.nextcurrent_node.next = new_nodereturn new_node# 删除链表中的所有值为val的节点def remove_elements(self, val):# 删除头结点while self.head_node is not None and self.head_node.data == val:self.head_node = self.head_node.nextself.length -= 1 # 维护长度# 删除非头结点current = self.head_nodewhile current is not None and current.next is not None:if current.next.data == val:current.next = current.next.nextself.length -= 1else:current = current.next# 打印链表def print_list(self):result = []current = self.head_nodewhile current is not None:result.append(str(current.data))current = current.nextprint(' '.join(result))if __name__ == "__main__":while True:try:n = int(input()) # 接收n的输入,表示链表的长度elements = list(map(int, input().split())) # 接收链表中的元素# 输入要删除的目标值val = int(input())# 创建链表并插入元素link_list = LinkList()for data in elements:link_list.insert(data) # 执行删除操作link_list.remove_elements(val)# 输出删除后的链表link_list.print_list()except:break
力扣题解代码如下:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:# 删除头结点while head is not None and head.val == val:head = head.next# 删除非头结点cur = headwhile cur is not None and cur.next is not None:if cur.next.val == val:cur.next = cur.next.nextelse:cur = cur.nextreturn head
- 设置虚拟头结点进行移除节点操作
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:# 设置一个虚拟头结点dummy_head = ListNode(next = head)# 遍历列表并删除值为val的节点current = dummy_headwhile current.next:if current.next.val == val:current.next = current.next.nextelse:current = current.nextreturn dummy_head.next




