203.移除链表元素
方法一:递归
class Solution3:
def removeElements(self, head: ListNode, val: int) -> ListNode:
if head is None:
return head
head.next = self.removeElements(head.next, val)
# 利用递归快速到达链表尾端,然后从后往前判断并删除重复元素
return head.next if head.val == val else head
# 每次递归返回的为当前递归层的head(若其值不为val)或head.next
# head.next及之后的链表在深层递归中已经做了删除值为val节点的处理,
# 因此只需要判断当前递归层的head值是否为val,从而决定head是删是留即可
方法二:添加一个虚拟头结点
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
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
707.设计链表
# 单链表
class Node(object):
def __init__(self, x=0):
self.val = x
self.next = None
class MyLinkedList(object):
def __init__(self):
self.head = Node()
self.size = 0 # 设置一个链表长度的属性,便于后续操作,注意每次增和删的时候都要更新
def get(self, index):
"""
:type index: int
:rtype: int
"""
if index < 0 or index >= self.size:
return -1
cur = self.head.next
while(index):
cur = cur.next
index -= 1
return cur.val
def addAtHead(self, val):
"""
:type val: int
:rtype: None
"""
new_node = Node(val)
new_node.next = self.head.next
self.head.next = new_node
self.size += 1
def addAtTail(self, val):
"""
:type val: int
:rtype: None
"""
new_node = Node(val)
cur = self.head
while(cur.next):
cur = cur.next
cur.next = new_node
self.size += 1
def addAtIndex(self, index, val):
"""
:type index: int
:type val: int
:rtype: None
"""
if index < 0:
self.addAtHead(val)
return
elif index == self.size:
self.addAtTail(val)
return
elif index > self.size:
return
node = Node(val)
pre = self.head
while(index):
pre = pre.next
index -= 1
node.next = pre.next
pre.next = node
self.size += 1
def deleteAtIndex(self, index):
"""
:type index: int
:rtype: None
"""
if index < 0 or index >= self.size:
return
pre = self.head
while(index):
pre = pre.next
index -= 1
pre.next = pre.next.next
self.size -= 1
# 双链表
# 相对于单链表, Node新增了prev属性
class Node:
def __init__(self, val):
self.val = val
self.prev = None
self.next = None
class MyLinkedList:
def __init__(self):
self._head, self._tail = Node(0), Node(0) # 虚拟节点
self._head.next, self._tail.prev = self._tail, self._head
self._count = 0 # 添加的节点数
def _get_node(self, index: int) -> Node:
# 当index小于_count//2时, 使用_head查找更快, 反之_tail更快
if index >= self._count // 2:
# 使用prev往前找
node = self._tail
for _ in range(self._count - index):
node = node.prev
else:
# 使用next往后找
node = self._head
for _ in range(index + 1):
node = node.next
return node
def get(self, index: int) -> int:
"""
Get the value of the index-th node in the linked list. If the index is invalid, return -1.
"""
if 0 <= index < self._count:
node = self._get_node(index)
return node.val
else:
return -1
def addAtHead(self, val: int) -> None:
"""
Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
"""
self._update(self._head, self._head.next, val)
def addAtTail(self, val: int) -> None:
"""
Append a node of value val to the last element of the linked list.
"""
self._update(self._tail.prev, self._tail, val)
def addAtIndex(self, index: int, val: int) -> None:
"""
Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
"""
if index < 0:
index = 0
elif index > self._count:
return
node = self._get_node(index)
self._update(node.prev, node, val)
def _update(self, prev: Node, next: Node, val: int) -> None:
"""
更新节点
:param prev: 相对于更新的前一个节点
:param next: 相对于更新的后一个节点
:param val: 要添加的节点值
"""
# 计数累加
self._count += 1
node = Node(val)
prev.next, next.prev = node, node
node.prev, node.next = prev, next
def deleteAtIndex(self, index: int) -> None:
"""
Delete the index-th node in the linked list, if the index is valid.
"""
if 0 <= index < self._count:
node = self._get_node(index)
# 计数-1
self._count -= 1
node.prev.next, node.next.prev = node.next, node.prev
206.反转链表
注意红色反转
引入temp值保存
递归可以根据双指针的方法来写
方法一:双指针
# 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 != None: #进入循环
temp = cur.next #因为cur下一个节点的链接因为反转断了,所以要提前保存好temp值才能赋值
cur.next = pre #开始反转
pre = cur #赋值,顺序千万不能错,不然cur的值就改了
cur = temp #赋值
return pre
方法二:递归
# 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:
def reverse(pre,cur):
if not cur:
return pre
tmp = cur.next
cur.next = pre
return reverse(cur,tmp)
return reverse(None,head)
- 今日学习的文章链接
- 自己看到题目的第一想法
毫无头绪
设计链表好难
- 看完代码随想录之后的想法
可以添加虚拟头节点
设计链表还需看视频学习
206的视频看懂了,讲得很清晰,通过画图,把赋值想明白了
- 自己实现过程中遇到哪些困难
链表好难,很多知识点不会,看视频讲解听懂了,要反复多看几遍但是到题目还是不行,不能死记硬背
- 今日收获,记录一下自己的学习时长
链表
class ListNode:
def __init__(self, val, next=None):
self.val = val
self.next = next