1 题目描述
2 解题思路
2.1 循环判断
先特判链表为空/只有一个元素的情况。
然后循环判断,如果下一个值等于val,那么就把当前位置的next再往后挪一个;如果值不等于val,向后推进一个。
但这样的话第一个元素没有判断过,需要特判。
# 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: ListNode, val: int) -> ListNode:
if(head==None):
return None
#先判断列表为空的情况
if(head.next==None):
if(head.val==val):
return None
else:
return head
#列表只有一个元素的情况
ret=head
while(head!=None and head.next!=None):
if(head.next.val==val):
head.next=head.next.next
else:
head=head.next
#循环判断链表第二个值及之后的值
if(ret.val==val):
return ret.next
else:
return ret
#特判第一个值
2.2 哨兵节点
如果删除的节点是中间的节点,则问题似乎非常简单:
->选择要删除节点的前一个结点 prev。
->将 prev 的 next 设置为要删除结点的 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: ListNode, val: int) -> ListNode: tmp=ListNode(val=0,next=head)#设置哨兵节点 print() ret=tmp#复制一个哨兵节点(因为tmp会一直向后走) while(tmp.next!=None): #tmp.next当前位置的下一个值(就是我们要和val比较的值—— if(tmp.next.val==val): tmp.next=tmp.next.next else: tmp=tmp.next #因为可能连续几个val,所以这里并不是每一次遍历,tmp都要赋值成tmp.next return ret.next