Loading......

文章背景图

Week1_Day5_LeetCode

2025-10-17
25
-
- 分钟

🧩 Week 1 · Day 5 — LeetCode Hot 100 链表进阶篇


1️⃣ 相交链表

🧠 题目描述

给你两个单链表的头节点 headAheadB ,请你找出并返回两个链表 相交的起始节点
如果两个链表不存在相交节点,返回 null

题目保证整个链式结构中 不存在环


💡 思路解析:双指针拼接法

核心思想是:
将两个链表「首尾相连」进行遍历,指针在两个链表上交替前进,最终会在相交点相遇;
若无相交节点,则同时到达 None

假设:

  • 链表 A 长度为 a + c

  • 链表 B 长度为 b + c

  • c 为公共部分长度

当两个指针分别走完两条链表(共 a + b + c 步)后:

  • 若存在相交,则相遇于交点;

  • 若不存在相交,则同时为 None


🧾 代码实现

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
        p, q = headA, headB
        while p is not q:
            p = p.next if p else headB
            q = q.next if q else headA
        return p

⚙️ 时间与空间复杂度

  • 时间复杂度:O(n + m)

  • 空间复杂度:O(1)


2️⃣ 环形链表 II

🧠 题目描述

给定一个链表的头节点 head,返回链表开始入环的第一个节点。
若链表中无环,则返回 None
不允许修改 链表结构。


💡 思路解析:快慢指针(Floyd 判圈算法)

  1. 第一阶段:判断是否存在环

    • 使用 slow 每次走一步,fast 每次走两步;

    • fast == slow,说明链表中存在环。

  2. 第二阶段:找到入环点

    • 设从头节点到入环点的距离为 a

    • 从入环点到相遇点的距离为 b

    • 环的长度为 c

    • 则有:fast = 2 * slow2(a + b) = a + b + kca = kc - b

    • 所以当 slow 从相遇点出发,head 从头出发,二者每次走一步,必定在入环点相遇。


🧾 代码实现

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        slow = fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if fast is slow:  # 相遇,存在环
                while slow is not head:  # 再走 a 步,相遇点即入环口
                    slow = slow.next
                    head = head.next
                return slow
        return None

⚙️ 时间与空间复杂度

  • 时间复杂度:O(n)

  • 空间复杂度:O(1)


3️⃣ 合并两个有序链表

🧠 题目描述

将两个升序链表合并为一个新的 升序链表 并返回。
新链表是通过拼接给定的两个链表的所有节点组成的。


💡 思路解析:双指针归并法

  1. 使用一个虚拟头节点 dum

  2. 维护指针 cur,依次比较 list1list2 的节点;

  3. 将较小的节点接在 cur.next

  4. 最后连接剩余部分。


🧾 代码实现

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        cur = dum = ListNode(0)
        while list1 and list2:
            if list1.val < list2.val:
                cur.next, list1 = list1, list1.next
            else:
                cur.next, list2 = list2, list2.next
            cur = cur.next
        cur.next = list1 if list1 else list2
        return dum.next

⚙️ 时间与空间复杂度

  • 时间复杂度:O(n + m)

  • 空间复杂度:O(1)


✅ 总结对比

题目

思路

技术核心

时间复杂度

空间复杂度

相交链表

双指针拼接

同时遍历两链表

O(n + m)

O(1)

环形链表 II

Floyd 判圈

快慢指针 + 数学推理

O(n)

O(1)

合并两个有序链表

双指针归并

虚拟头节点技巧

O(n + m)

O(1)

评论交流