Leetcode: 相交链表

41 阅读2分钟

原题:leetcode.cn/problems/in…

题目描述

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

解题思路

  1. 双指针路径补偿法
    • 初始化两个指针分别指向两个链表头节点
    • 指针同步遍历链表,到达尾部时跳转至另一链表头部
  2. 相遇点即交点
    • 若链表相交,两指针会在交点相遇
    • 若不相交,两指针最终同时到达尾部(null)
  3. 路径长度分析
    • 每个指针都遍历"链表A非公共部分 + 链表B非公共部分 + 公共部分"
    • 路径长度相等确保必然相遇
  4. 边界处理
    • 处理空链表输入
    • 处理无交点情况

关键洞察

  1. 路径补偿原理
    • 交换遍历路径消除长度差
    • 保证两指针同时遍历总长度L1+L2
  2. 交点特性
    • 相交点后序列完全一致
    • 相遇点即为首个公共节点
  3. 终止条件
    • 指针相遇或同时为null终止
  4. 效率优化
    • 无需计算链表长度
    • 无需额外存储空间

复杂度分析

指标说明
时间复杂度O(m+n):最多遍历两个链表各一次
空间复杂度O(1):仅使用两个指针

代码实现

/**
 * @link {https://leetcode.cn/problems/intersection-of-two-linked-lists/}
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function (headA, headB) {
    if (headA === null || headB === null) {
        return null;
    }

    let pA = headA, pB = headB;
    while (pA !== pB) {
        pA = pA === null ? headB : pA.next;
        pB = pB === null ? headA : pB.next;
    }

    return pA;
}; 

实际应用场景

  1. 内存管理系统:检测两个对象引用是否共享相同内存段`
  2. 版本控制系统:查找代码分支的最近共同祖先提交`
  3. 社交网络分析:查找两个用户的最短关联路径`
  4. 生物信息学:DNA序列中查找共同片段起始点`

相似题目