跳至内容
返回

LeetCode 160 - 相交链表

发布于:  at  04:54 下午

题目

判断两条链表是否相交,如果相交则返回相交的第一个节点,否则返回 null。

这里的”相交”指的是同一个节点对象(引用相等),而不是节点值相等。

示例:

相交情况:

 A: a1 → a2 → a3
               ↘
                c1 → c2 → c3 → null
               ↗
 B: b1 → b2
 ​
 交点:c1(同一个节点引用)

不相交情况:

 A: a1 → a2 → a3 → null
 B: b1 → b2 → null

解题思路

使用双指针换头法,核心思想是:让两个指针分别走完 A+B 和 B+A 的总路程,因为总长度相等,它们会在交点相遇。

算法原理

假设:

则有:a = x + cb = y + c

因为 x + c + y = y + c + x,两个指针会同时到达交点 c 的起始位置。

如果不相交(c = 0),两个指针最终都会同时到达 null。

代码实现

 public class Solution {
     public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
         // p1: 遍历链表 A,遍历完 A 后继续遍历 B
         // p2: 遍历链表 B,遍历完 B 后继续遍历 A
         ListNode p1 = headA;
         ListNode p2 = headB;
 ​
         while (p1 != p2) {
             // p1 走完 A 换到 B,继续走
             if (p1 == null) {
                 p1 = headB;
             } else {
                 p1 = p1.next;
             }
 ​
             // p2 走完 B 换到 A,继续走
             if (p2 == null) {
                 p2 = headA;
             } else {
                 p2 = p2.next;
             }
         }
 ​
         // 返回相交节点;若不相交,最终 p1==p2==null
         return p1;
     }
 }

代码解释

  1. 初始化双指针:p1 从 headA 开始,p2 从 headB 开始
  2. 循环条件p1 != p2,直到两个指针相遇
  3. 指针移动逻辑
    • 如果指针为 null,说明走完了当前链表,切换到另一条链表的头部
    • 否则继续向后移动
  4. 返回结果
    • 相交:返回交点节点
    • 不相交:返回 null(因为两个指针最终都会到达 null)

执行过程示例

假设 A 长度 5,B 长度 3,公共部分长度 2:

 A: a1 → a2 → a3 → c1 → c2
 B: b1 → c1 → c2
 ​
 p1 路径: a1 → a2 → a3 → c1 → c2 → null → b1 → c1
 p2 路径: b1 → c1 → c2 → null → a1 → a2 → a3 → c1
 ​
 在 c1 处相遇

速记

双指针换头走,p1 走 A+B,p2 走 B+A,路程相等必在交点相遇,无交点则同时到 null。

注意点

  1. 判断相交用引用相等:用 == 比较节点对象,不是比较值
  2. 换头时机:指针为 null 时换到另一条链表,不是到达 null 前的最后一个节点
  3. 循环终止条件p1 != p2,不需要额外的计数器
  4. 特殊情况处理
    • 两个链表都为空:第一次循环 p1 == p2 == null,直接返回 null
    • 一个为空一个不为空:也能正确处理,最终都会到达 null

复杂度分析


建议修改
在以下平台分享此文章:

下一篇
LeetCode 141 - 环形链表