题目链接
法一:
1.删除节点分为两种情况,删除头节点和非头节点
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
while head and head.val == 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
法二:
# 2.添加一个虚拟头节点,对头节点的删除操作与其他节点一样
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
pre_node = ListNode(next=head)
node = pre_node
while node.next:
if node.next.val == val:
node.next = node.next.next
else:
node = node.next
return pre_node.next
这段代码是用于删除链表中值为 `val` 的节点的方法。下面逐行解释它的工作原理:
1. `pre_node = ListNode(next=head)`:这一行创建了一个名为 `pre_node` 的新节点,它的 `next` 属性指向链表的头节点 `head`。这个新节点作为链表的伪头节点,有助于处理头节点本身是否需要被删除的情况。
2. `node = pre_node`:将 `node` 初始化为 `pre_node`,用于迭代遍历链表。
3. `while node.next:`:这是一个循环,用于遍历链表。如果 `node.next` 不为空(即还有节点要遍历),则进入循环。
4. `if node.next.val == val:`:这个条件检查当前节点的下一个节点是否具有值等于 `val`。如果相等,表示需要删除下一个节点。
5. `node.next = node.next.next`:如果需要删除下一个节点,直接将当前节点的 `next` 指针跳过下一个节点,指向下下个节点,从而删除了中间的节点。
6. `else:`:如果下一个节点的值不等于 `val`,那么我们只需将 `node` 移动到下一个节点,即 `node = node.next`,以便继续遍历下一个节点。
7. 最后,`return pre_node.next`:返回经过删除操作后的链表的头节点,即链表的第一个节点,这个节点不再包含值为 `val` 的节点。
这段代码的关键在于引入了一个伪头节点 `pre_node`,它使得链表的头节点也可以像其他节点一样被处理,确保链表操作的一致性。通过这种方式,可以避免处理头节点的特殊情况,使代码更简洁和健壮。
题目链接
class Node:
def __init__(self, _val):
self.val = _val
self.prev = None
self.next = None
class MyLinkedList:
def __init__(self):
self.he = Node(-1)
self.ta = Node(-1)
self.he.next = self.ta
self.ta.prev = self.he
self.sz = 0
def get(self, index: int) -> int:
node = self.getNode(index)
return node.val if node else -1
def addAtHead(self, val: int) -> None:
node = Node(val)
node.next = self.he.next
node.prev = self.he
self.he.next.prev = node
self.he.next = node
self.sz += 1
def addAtTail(self, val: int) -> None:
node = Node(val)
node.prev = self.ta.prev
node.next = self.ta
self.ta.prev.next = node
self.ta.prev = node
self.sz += 1
def addAtIndex(self, index: int, val: int) -> None:
if index > self.sz:
return
if index <= 0:
self.addAtHead(val)
elif index == self.sz:
self.addAtTail(val)
else:
node, cur = Node(val), self.getNode(index)
node.next = cur
node.prev = cur.prev
cur.prev.next = node
cur.prev = node
self.sz += 1
def deleteAtIndex(self, index: int) -> None:
node = self.getNode(index)
if node:
node.prev.next = node.next
node.next.prev = node.prev
self.sz -= 1
def getNode(self, index: int) -> Node | None:
isLeft = index < self.sz / 2
if not isLeft:
index = self.sz - index - 1
cur = self.he.next if isLeft else self.ta.prev
while cur != self.he and cur != self.ta:
if index == 0:
return cur
index -= 1
cur = cur.next if isLeft else cur.prev
return None
题目链接
class Solution(object):
def reverseList(self, head):
# 递归终止条件是当前为空,或者下一个节点为空
if(head==None or head.next==None):
return head
# 这里的cur就是最后一个节点
cur = self.reverseList(head.next)
# 如果链表是 1->2->3->4->5,那么此时的cur就是5
# 而head是4,head的下一个是5,下下一个是空
# 所以head.next.next 就是5->4
head.next.next = head
# 防止链表循环,需要将head.next设置为空
head.next = None
# 每层递归函数都返回cur,也就是最后一个节点
return cur
这段代码是用于反转一个单链表的 Python 解法,它使用了递归的方式实现。
1. `def reverseList(self, head):`:这是一个类方法,用于反转单链表。它接收一个头节点 `head` 作为参数,返回一个新的头节点,即反转后的链表的新头部。
2. `if(head==None or head.next==None):`:这是递归的终止条件。如果当前节点 `head` 为空或者下一个节点为空,那么无需反转,直接返回 `head`。
3. `cur = self.reverseList(head.next)`:这里进行递归调用,调用 `reverseList` 方法来反转从当前节点的下一个节点开始的链表,并将返回值赋给 `cur`。
4. `head.next.next = head`:这一行的目的是反转当前节点 `head` 和它的下一个节点之间的连接。它将下一个节点的 `next` 指针指向当前节点,实现反转操作。
5. `head.next = None`:这一行的目的是将当前节点的 `next` 指针设置为空,以防止链表循环。
6. `return cur`:递归函数的每一层都返回 `cur`,也就是反转后链表的新头部。
这个递归过程的关键在于,递归函数会一直调用自身,直到链表的最后一个节点,然后开始反转节点,并不断向上层返回反转后的链表。最终,整个链表都被反转,而递归终止时,`cur` 指向反转后的新头节点。