LC 203 移除链表元素
法一,直接移除,注意分移除元素是否处于头节点两种情况讨论。
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
pre = None
temp = head
while pre == None:
if temp == None:
return None
'''
不加上面两句话会产生以下报错,大概是有些测试用例头节点为空,
而空节点没有next属性,没判断
AttributeError: 'NoneType' object has no attribute 'val'
'''
if temp.val == val:
temp = temp.next
head = temp
else:
pre = temp
temp = temp.next
while temp:
if temp.val == val:
pre.next = temp.next
temp = temp.next
elif temp.val != val:
pre = temp
temp = temp.next
return head
法二,虚拟头节点。
新建一个虚拟头节点,指向原链表的头节点,那么原链表的头节点永远都在新链表的中间,便可以统一操作方法:在链表中间删除元素。可以看到这种方法非常简洁,不可谓不赏心悦目!
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
dummy = ListNode(next = head)
temp = dummy
while temp and temp.next:
if temp.next.val == val:
temp.next = temp.next.next
else:
temp = temp.next
return dummy.next
LC707 设计链表
恶心的一题,一开始本不想用虚拟节点直接操作链表写一遍,每次提交各种报错,遂放弃。。
使用虚拟节点后也是各种报错,算了算了看讲解吧,跟着讲解的思路和网站上的代码敲了一遍,还是不熟练,留待二刷
LC 206 反转链表
法一,双指针法+缓存
初始化pre指针为空,current指针指向头节点。需要做的就是在pre和current遍历过程中不断让current指向pre,但是由于current已经指向了pre,无法获取到后续的节点,那先新建一个temp在改变current指向前保存curren.next即可,代码如下
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
pre = None
current = head
while current:
temp = current.next
current.next = pre
pre = current
current = temp
return pre
法二,递归
递归法也是根据双指针法来的,但是比较晦涩。对比着双指针看稍微好理解一点
class Solution: def reverseList(self, head: ListNode) -> ListNode: return self.reverse(head, None) ''' 事实上这就是双指针的第一句话,即初始化pre为None以及将cur指向head 在递归里的理解就是先把head指向none,后面的节点通过递归调用不断指向前一个节点 ''' def reverse(self, cur: ListNode, pre: ListNode) -> ListNode: if cur == None:#递归出口,即指针cur指向了空 return pre temp = cur.next#利用temp在指针指向pre前,获取cur.next cur.next = pre return self.reverse(temp, cur)