Leetcode Top100答案和解释 -- Python版本(链表)

160. 相交链表

python 复制代码
class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
        p, q = headA, headB

        while p is not q:
            if p:
                p = p.next
            else:
                p = headB
            
            if q:
                q = q.next
            else:
                q = headA

        return q
  1. 初步思路标题(哈希集合法)

    最直接的解法是遍历第一个链表,将所有节点存入哈希集合,然后遍历第二个链表检查是否有节点在集合中。这种方法虽然直观,但需要O(m)或O(n)的额外空间,不符合空间复杂度O(1)的要求。

  2. 优化思路标题(双指针交替遍历法)

    • 优化方向1:利用两个指针分别从两个链表头开始遍历,当指针到达末尾时,将其重定向到另一个链表的头部

    • 优化方向2:通过这种交替遍历的方式,两个指针最终会在相交节点相遇,或者同时到达末尾(null)

  3. 关键策略优势

    • 策略带来的具体好处1:无需额外存储空间,空间复杂度降为O(1)

    • 策略带来的具体好处2:通过消除长度差,确保两个指针在第二次遍历时能够同步到达相交点

    • 策略带来的具体好处3:代码简洁,只需要简单的指针操作即可实现

  4. 具体实现

复制代码
class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
        p, q = headA, headB

        # 当两个指针不相遇时继续遍历
        while p is not q:
            # p指针移动到下一个节点,如果到达末尾则从headB开始
            if p:
                p = p.next
            else:
                p = headB
            
            # q指针移动到下一个节点,如果到达末尾则从headA开始
            if q:
                q = q.next
            else:
                q = headA

        # 返回相遇节点(如果没有相交,则返回null)
        return q

206. 反转链表

python 复制代码
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        p = None
        c = head
        
        while c:
            n = c.next  
            c.next = p      
            p = c          
            c = n      
            
        return p
  1. 初步思路标题(借助外部数组法)

    最直观的解法是遍历链表将所有节点值存入数组,然后反向遍历数组重新构建链表。这种方法虽然易于理解,但需要O(n)的额外空间存储节点值,且破坏了原链表的结构,不符合题目对原地反转的隐含要求。

  2. 优化思路标题(迭代指针反转法)

    • 优化方向1:使用三个指针(前驱p、当前c、后继n)在遍历过程中逐步反转每个节点的指向

    • 优化方向2:通过保存当前节点的下一个节点,防止在改变指向后丢失后续节点的访问能力

  3. 关键策略优势

    • 策略带来的具体好处1:只需遍历一次链表,时间复杂度为O(n)

    • 策略带来的具体好处2:仅使用三个指针变量,空间复杂度为O(1),实现真正的原地反转

    • 策略带来的具体好处3:能够正确处理空链表和单节点链表的边界情况

  4. 具体实现

复制代码
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        p = None  # 前驱指针,初始为None
        c = head  # 当前指针,从链表头开始
        
        while c:  # 当当前节点不为空时继续遍历
            n = c.next   # 保存下一个节点,防止丢失
            c.next = p   # 将当前节点的next指向前驱,完成反转
            p = c        # 前驱指针移动到当前节点
            c = n        # 当前指针移动到下一个节点
            
        return p  # 返回新的头节点(原链表的最后一个节点)
python 复制代码
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        
        n = self.reverseList(head.next)
        head.next.next = head
        head.next = None

        return n
  1. 初步思路标题(迭代指针反转法)

    常规解法是使用三个指针迭代遍历链表,逐个反转节点的指向。这种方法直观且高效,但需要手动维护指针关系,代码相对繁琐。

  2. 优化思路标题(递归回溯反转法)

    • 优化方向1:利用递归调用栈天然的后进先出特性,先递归到链表末尾,然后在回溯过程中逐步反转指针方向

    • 优化方向2:将问题分解为"反转当前节点之后的链表"这一子问题,通过递归调用解决子问题后再处理当前节点

  3. 关键策略优势

    • 策略带来的具体好处1:代码极其简洁优雅,只需几行就能实现完整功能

    • 策略带来的具体好处2:递归思路更符合数学归纳法的思维方式,易于理解和证明正确性

    • 策略带来的具体好处3:虽然使用调用栈(空间复杂度O(n)),但在链表反转的场景中通常也是可接受的

  4. 具体实现

复制代码
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # 递归终止条件:空链表或只有一个节点
        if not head or not head.next:
            return head
        
        # 递归反转后续链表,返回新的头节点
        n = self.reverseList(head.next)
        
        # 关键步骤:将当前节点的下一个节点的next指向当前节点
        # 例如:原链表 ... -> head -> next -> ...
        # 反转后变为 ... -> next -> head -> ...
        head.next.next = head
        head.next = None  # 防止形成环
        
        return n
相关推荐
niuniudengdeng2 小时前
六面独立转动魔方还原机器人设计与实现
数学·算法·机器人
ghie90902 小时前
基于MATLAB的A*算法避障路径规划实现
人工智能·算法·matlab
雾岛听蓝3 小时前
C文件操作与系统IO
linux·c语言·开发语言·经验分享·笔记·算法
zh路西法3 小时前
【宇树机器人强化学习】(一):PPO算法的python实现与解析
python·深度学习·算法·机器学习·机器人
随意起个昵称3 小时前
【贪心】选择尽量多的不相交区间
数据结构·算法
章小幽3 小时前
LeetCode-35.搜索插入位置
数据结构·算法·leetcode
放下华子我只抽RuiKe53 小时前
机器学习全景指南-探索篇——发现数据内在结构的聚类算法
人工智能·深度学习·算法·机器学习·语言模型·数据挖掘·聚类
Yupureki3 小时前
《C++实战项目-高并发内存池》3.ThreadCache构造
服务器·c语言·c++·算法·哈希算法
j_xxx404_4 小时前
C++算法:一维/二维前缀和算法模板题
开发语言·数据结构·c++·算法