代码随想录算法训练营day03| 203.移除链表元素、707.设计链表、206.反转链表

Leetcode 203.移除链表元素

题目链接

法一:

 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`,它使得链表的头节点也可以像其他节点一样被处理,确保链表操作的一致性。通过这种方式,可以避免处理头节点的特殊情况,使代码更简洁和健壮。

Leetcode 707.设计链表

题目链接

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

Leetcode 206.反转链表

题目链接

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` 指向反转后的新头节点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值