1:题目描述(力扣)
给你一个链表的头节点 head
和一个整数 val
,请你删除链表中所有满足 Node.val == val
的节点,并返回 新的头节点 。
2:解题思路
先来看一下链表的基础理论:(代码随想录-链表)
第一种解法:在原链表的基础上删除节点
分两种情况:
第一种:删除的节点是头节点
第二种:删除的节点不是头节点
这两种情况的处理方式不一样,处理方式如下:
删除的节点是头节点:
- 先判断头节点是否为空,并且头节点的值是否等于目标值,都满足,则头节点 等于头节点的下一个节点(head=head.next)。此处判断需要使用while,而不是if。因为当链表为:1>1>1>1>1>None,目标值为1时,删除一个头节点后,下一个头节点还满足条件,所以使用while。
删除的节点不是头节点:
- 先定义一个新的节点cur,将头节点赋值给新节点cur,判断新节点和新节点的下一节点是否为空(cur != None and cur.next != None);
- 再判断新节点的下一个节点的值是否等于目标值,等于目标值:就将新节点的下一个节点指向新节点的下一个节点的下一个节点(cur.next = cur.next.next);不等于目标值:将新节点的下一个节点赋值给新节点(cur=cur.next)
最后返回头节点(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, val):
# 第一种解法:原链表删除节点
# 当需要删除的节点是头节点
while head != None and head.val == val:
head = head.next
# 当需要删除的节点不是头节点
cur = head
while cur !=None and cur.next != None:
if cur.next.val == val:
cur.next = cur.next.next
else:
cur = cur.next
return head
第二种解法:使用虚拟头节点
添加一个虚拟节点,作为链表的头节点。这样就避免了需要处理第一种解法中的两种情况。有了虚拟头节点,需要删除的节点就不是头节点了。
思路如下:
第一步:先添加一个虚拟节点dummy_head,并将头节点指向它。
第二步:定义一个新节点cur,将虚拟节点赋值给新节点,cur = dummy_head。
第三步:判断新节点的下一个节点是否为空;再判断新节点下一节点的值是否等于目标值:等于目标值,则新节点的下一节点等于新节点的下一节点的下一节点(cur.next = cur.next.next);不等于目标值,则新节点等于新节点的下一节点(cur=cur.next)
第四步:返回虚拟节点的下一节点,dummy_dead.next,因为需要返回原链表的头节点,所以返回虚拟节点的下一节点
代码展示:
# 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, val):
# 第二种解法:使用虚拟头节点:加一个虚拟节点作为头节点,
# 这样避免了删除的节点是头节点和不是头节点的处理方式不一致的问题
dummy_head = ListNode(next=head) # 添加一个虚拟节点
cur = dummy_head
while cur.next != None:
if cur.next.val == val:
cur.next = cur.next.next
else:
cur = cur.next
return dummy_head.next