leetcode(4):链表二,环链表,交叉链表

  • 虚拟头节点可以防止在链表头和链表尾部的不同规则,使得一个规则可以完成对头和中间的操作
  • 注意and的逻辑
  • 非常重要的是虚拟头节点和快慢指针
  • 重回头节点也是非常重要的思路

24. 两两交换链表中的节点

感觉写的时候有点迷迷糊糊的,但是结果竟然对了

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:

        # 尝试使用创设的虚拟节点来进行互换
        node0 = dummy = ListNode(next = head)
        node1 = head
    
        while node1 and node1.next:
            node2 = node1.next

            node0.next = node1.next
            node1.next = node2.next
            node2.next = node1
            
            node0 = node1
            node1 = node1.next
        
        return dummy.next

注意and的逻辑:

  • 在 Python 中,如果 node1 是尾节点(即 node1None),node1 and node1.next 不会报错。这是因为 Python 中的 and 运算符是短路运算符,它会在第一个条件为假时立即停止并返回假。
  • 因此,如果 node1 是尾节点,条件 node1 and node1.next 中的第一个条件 node1 会被解释为假(False),然后 Python 将停止计算并返回假,而不会进一步检查 node1.next 是否存在,也就不会报错。

19.删除链表的倒数第N个节点

利用了虚拟头节点进行运用,但是结果上还是要分类讨论是否重新定义了head

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        p = head
        p_dele_before = ListNode(next = head)
        i = 1
        while p.next != None:
            if i >= n:
                p_dele_before = p_dele_before.next
            p = p.next
            i += 1
        
        if i > n and i != 1:
            p_dele_before.next = p_dele_before.next.next
            return head
        elif i == n and i != 1:
            p_dele_before.next = p_dele_before.next.next
            return p_dele_before.next
        else:
            return None

更简便的解法

  • 进一步理解python指向的对象
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        left = right = dummy = ListNode(next = head)
        for _ in range(n):
            right = right.next
        while right.next:
            left = left.next
            right = right.next
        left.next = left.next.next
        return dummy.next

面试题 02.07. 链表相交

开始想法是每个往后移动一个,依次往后遍历,最多为2n,但是确实不能实现所有的情况

题解很牛,学到了😭

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        pointerA = headA
        pointerB = headB

        while pointerA != pointerB:
            pointerA = pointerA.next if pointerA else headB
            pointerB = pointerB.next if pointerB else headA

        return pointerA

摘自leetcode题解

142.环形链表II

终于看懂了视频,最开始想分两步来写,先找相遇点,再找结果;看到答案很巧妙,之间嵌套了循环。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                break

        if fast and fast.next: pass
        else: return None
        
        while head != fast:
            head = head.next
            fast = fast.next
        
        return fast
  • 虚拟头节点可以防止在链表头和链表尾部的不同规则,使得一个规则可以完成对头和中间的操作
  • 注意and的逻辑
  • 非常重要的是虚拟头节点和快慢指针,基本问题都可以解决

24. 两两交换链表中的节点

感觉写的时候有点迷迷糊糊的,但是结果竟然对了

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:

        # 尝试使用创设的虚拟节点来进行互换
        node0 = dummy = ListNode(next = head)
        node1 = head
    
        while node1 and node1.next:
            node2 = node1.next

            node0.next = node1.next
            node1.next = node2.next
            node2.next = node1
            
            node0 = node1
            node1 = node1.next
        
        return dummy.next

注意and的逻辑:

  • 在 Python 中,如果 node1 是尾节点(即 node1None),node1 and node1.next 不会报错。这是因为 Python 中的 and 运算符是短路运算符,它会在第一个条件为假时立即停止并返回假。
  • 因此,如果 node1 是尾节点,条件 node1 and node1.next 中的第一个条件 node1 会被解释为假(False),然后 Python 将停止计算并返回假,而不会进一步检查 node1.next 是否存在,也就不会报错。

19.删除链表的倒数第N个节点

利用了虚拟头节点进行运用,但是结果上还是要分类讨论是否重新定义了head

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        p = head
        p_dele_before = ListNode(next = head)
        i = 1
        while p.next != None:
            if i >= n:
                p_dele_before = p_dele_before.next
            p = p.next
            i += 1
        
        if i > n and i != 1:
            p_dele_before.next = p_dele_before.next.next
            return head
        elif i == n and i != 1:
            p_dele_before.next = p_dele_before.next.next
            return p_dele_before.next
        else:
            return None

更简便的解法

  • 进一步理解python指向的对象
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        left = right = dummy = ListNode(next = head)
        for _ in range(n):
            right = right.next
        while right.next:
            left = left.next
            right = right.next
        left.next = left.next.next
        return dummy.next

面试题 02.07. 链表相交

开始想法是每个往后移动一个,依次往后遍历,最多为2n,但是确实不能实现所有的情况

题解很牛,学到了😭

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        pointerA = headA
        pointerB = headB

        while pointerA != pointerB:
            pointerA = pointerA.next if pointerA else headB
            pointerB = pointerB.next if pointerB else headA

        return pointerA

 

摘自leetcode题解

142.环形链表II

终于看懂了视频,最开始想分两步来写,先找相遇点,再找结果;看到答案很巧妙,之间嵌套了循环。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        slow, fast = head, head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                break

        if fast and fast.next: pass
        else: return None
        
        while head != fast:
            head = head.next
            fast = fast.next
        
        return fast

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值