LeetCode Day03 | 203. 移除链表元素、707. 设计链表、206. 反转链表

203. 移除链表元素

难度:☆2

注意链表节点(ListNode)的类和构造函数怎么写。

a. 原链表移除元素

如果头节点需要移除/如果头节点不需要移除。注意,用while判断头节点是否为val,而且在while中条件判断head和cur是否存在。

# 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]:
        while head and head.val == val:
            head = head.next
        cur = head
        while cur and cur.next:
            if cur.next.val == val:
                cur.next = cur.next.next
            else:
                cur = cur.next
        return head

b. 加入虚拟头节点

为了方便解决头节点就是目标节点的情况,设置一个虚拟头节点(哑节点 dummyHead),代码可以统一。

class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        dummyHead = ListNode(next=head)
        cur = dummyHead
        while cur.next:
            if cur.next.val == val:
                cur.next = cur.next.next
            else:
                cur = cur.next
        return dummyHead.next

c. 递归法

以上都是迭代法,还可以用递归法解决本题。

class Solution:
    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

707. 设计链表

难度:☆3

a. 单链表

设置一个虚拟头节点(哑节点 dummyHead),设置一个计数器记录当前节点总数。自行创建一个ListNode类。不妨假设4个节点,index=3方便判断循环终止条件,也可以用index=0作为极端条件直接判断。注意类的属性和方法要写清self,漏写必然会报错。

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


class MyLinkedList:
    def __init__(self):
        self._dummyHead = ListNode()
        self._count = 0


    def get(self, index: int) -> int:
        if index < 0 or index >= self._count:
            return -1
        cur = self._dummyHead
        while index >= 0:
            cur = cur.next
            index -= 1
        return cur.val


    def addAtHead(self, val: int) -> None:
        self.addAtIndex(0, val)


    def addAtTail(self, val: int) -> None:
        self.addAtIndex(self._count, val)


    def addAtIndex(self, index: int, val: int) -> None:
        if index <= 0:
            addNode = ListNode(val, self._dummyHead.next)
            self._dummyHead.next = addNode
            self._count += 1
        elif index > 0 and index <= self._count:
            cur = self._dummyHead
            while index > 0:
                cur = cur.next
                index -= 1
            addNode = ListNode(val, cur.next)
            cur.next = addNode
            self._count += 1
            
        
    def deleteAtIndex(self, index: int) -> None:
        if index >= 0 and index < self._count:
            cur = self._dummyHead
            while index > 0:
                cur = cur.next
                index -= 1
            cur.next = cur.next.next
            self._count -= 1

b. 双链表

每个节点既有前驱,又有后继,方便增、删、查的函数选择从头开始还是从尾开始。用时更少,但前驱、后继的操作更多。

206. 反转链表

难度:☆3

a. 双指针(迭代法)

双指针前后间隔为1,不是2,共同向前。让cur指向的节点指向pre指向的节点。注意要用一个临时变量temp存储cur的下一个节点,之后再赋值给cur。cur初始为头节点,pre初始为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: Optional[ListNode]) -> Optional[ListNode]:
        # 迭代法 前后双指针
        cur = head
        pre = None
        while cur:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        return pre

b. 递归法1

根据双指针法的思路,设计一个递归函数,不断让cur指向pre,当cur为空的时候结束。在递归法中,初始化的逻辑和双指针法是一样的:cur = head,pre = None,写法不同。

class Solution:
    # 递归法
    def reverseList(self, head: ListNode) -> ListNode:
        return self.reverse(head, None)
    
    def reverse(self, cur, pre):
        if cur is None: 
            return pre
        temp = cur.next
        cur.next = pre
        return self.reverse(temp, cur)

c. 递归法2

假设链表的其余部分已经被反转,现在应该如何反转它前面的部分?若从节点 nk+1 到 nm 已经被反转,而我们正处于 nk,我们希望 nk+1 的下一个节点指向 nk:nk.next.next = nk。需要注意的是 n1 的下一个节点必须指向None。

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head       
        newHead = self.reverseList(head.next)
        head.next.next = head
        head.next = None
        return newHead
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值