203.移除链表元素
思路:知道移除元素的操作过程,但整段链表的移除过程不清晰
法一:直接使用原来的链表来进行移除节点操作:
# 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:
while head and head.val == val:
# 让自head起第一个值不为val的节点作为头节点
# 退出while循环时,有两种情况
# 1 head为空(即链表左右节点值均为val,则进入if并return
# 2 找到了第一个值不为val的节点(是真正的头节点),那么之后就开始对该节点之后的非头节点的元素进行遍历处理
head = head.next
if head is None:
return head
node = head
while node.next:
if node.next.val == val:
node.next = node.next.next
else:
node = node.next
return head#return node更好,万一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]:
virtual_node = ListNode(next=head) # 设置一个虚拟节点,下一个指向头节点
node = virtual_node
if head is None:
return head
while node.next:
if node.next.val == val:
node.next = node.next.next
else:
node = node.next
return virtual_node.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: Optional[ListNode], val: int
) -> Optional[ListNode]:#递归无虚拟节点
if head is None:
return head
head.next=self.removeElements(head.next,val)#head寻找下一个节点的过程被递归
if head.val==val:
next_node=head.next
else:
next_node=head
return next_node
707.设计链表
class LinkNode:#首先得定义节点
def __init__(self,val=0,next=None):#注意初始定义
self.val=val
self.next=next
class MyLinkedList:#设计单链表
def __init__(self):
self.head=LinkNode()#定义头节点
self.size=0#一开始长度为0
def get(self, index: int) -> int:
if index<0 or index>=self.size:
return -1
current=self.head.next
for i in range(index):
current=current.next
return current.val#最后返回其值
def addAtHead(self, val: int) -> None:
self.head.next=LinkNode(val,self.head.next)
self.size+=1#长度加一
def addAtTail(self, val: int) -> None:
current=self.head
while current.next:
current=current.next
current.next=LinkNode(val)
self.size+=1
def addAtIndex(self, index: int, val: int) -> None:
if index<0 or index>self.size:
return
current=self.head
for i in range(index):
current=current.next
current.next=LinkNode(val,current.next)
self.size+=1
def deleteAtIndex(self, index: int) -> None:
if index<0 or index>=self.size:#index从0开始,所以有=号
return
current=self.head
for i in range(index):
current=current.next
current.next=current.next.next
self.size-=1
双链表
class ListNode:#双链表
def __init__(self,val=0,prev=None,next=None):
self.val=val
self.next=next
self.prev=prev
class MyLinkedList:
def __init__(self):
self.head=None
self.tail=None
self.size=0
def get(self,index:int)->int:
if index<0 or index>=self.size:
return -1
if index<self.size//2:
current=self.head
for i in range(index):
current=current.next
else:
current=self.tail
for i in range(self.size-index-1):
current=current.prev
return current.val
def addAtHead(self, val: int) -> None:
new_node = ListNode(val,None,self.head)
if self.head:
self.head.prev = new_node
else:
self.tail = new_node
self.head = new_node
self.size += 1
def addAtTail(self, val: int) -> None:
new_node = ListNode(val, self.tail, None)
if self.tail:
self.tail.next = new_node
else:
self.head = new_node
self.tail = new_node
self.size += 1
def addAtIndex(self, index: int, val: int) -> None:
if index < 0 or index > self.size:
return
if index == 0:
self.addAtHead(val)#为0加在头节点
elif index == self.size:
self.addAtTail(val)
else:
if index < self.size // 2:#判断在哪一边
current = self.head
for i in range(index - 1):#从前往后遍历到他的前一位
current = current.next#然后current指向前一位的下一位
else:
current = self.tail
for i in range(self.size - index):#从后往前
current = current.prev
new_node = ListNode(val, current, current.next)
current.next.prev = new_node
current.next = new_node
self.size += 1
def deleteAtIndex(self,index:int)->None:#四种情况
if index<0 or index>=self.size:
return
if index==0:
self.head=self.head.next#先后移动,再删除
if self.head:
self.head.prev=None
else:
self.tail=None
elif index==self.size-1:
self.tail=self.tail.prev#先前移,再删除
if self.tail:
self.tail.next=None
else:
self.head=None
else:
if index<self.size//2:#先找到再删除
current=self.head
for i in range(index):
current=current.next
else:
current=self.tail
for i in range(self.size-index-1):
current=current.prev
current.prev.next=current.next#不用处理删去的节点
current.next.prev=current.prev
self.size-=1
206.反转链表
双指针:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:#双指针的写法
cur=head
pre=None
while cur:
temp=cur.next#用一个temp来存cur,否则链接断后,cur无法移动到下一个位置
cur.next=pre
pre=cur
cur=temp
return pre#cur最后指向none
递归:本质也是双指针
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: ListNode) -> ListNode:#递归的写法
return self.reverse(head,None)#cur最后为头节点
def reverse(self,cur:ListNode,pre:ListNode)->ListNode:
if cur ==None:#退出条件
return pre
else:
temp=cur.next
cur.next=pre#一个子过程,存储加反转
return self.reverse(temp,cur)#之前的temp和cur传入