[链表] - 代码随想录 160. 相交链表
题目要求
给定两个单链表的头节点 headA 和 headB,请找出并返回两链表相交的起始节点 ;若两链表无交点,返回 null。
解题思路
本题的核心是在常数空间内高效找到相交节点 。常规思路(如哈希表存储节点)会占用 O(n) 额外空间,而双指针法是更优的选择,其核心逻辑基于「总路程相等」的数学原理:
方法原理
- 双指针初始化 :两个指针
A、B分别从headA、headB头节点出发。 - 交替遍历逻辑 :指针走完自身链表后,转走另一个链表(
A走完headA转走headB,B走完headB转走headA)。 - 相遇条件 :
- 若两链表相交:设
headA长度为a、headB为b,相交部分长度为c,则A的总路程为a + (b - c),B为b + (a - c),两者相等,因此会在相交节点处相遇。 - 若两链表无相交:指针最终会同时走完
a + b步,均指向null。
- 若两链表相交:设
实现代码
java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 双指针初始化为两链表的头节点
ListNode A = headA, B = headB;
// 循环终止条件:指针相遇(交点或同时为null)
while (A != B) {
// A指针:非空则走下一步,否则转走headB
A = (A != null) ? A.next : headB;
// B指针:非空则走下一步,否则转走headA
B = (B != null) ? B.next : headA;
}
// 返回相遇节点(或null)
return A;
}
}
复杂度分析
- 时间复杂度 :O(m + n),其中
m、n为两链表长度。每个节点最多被访问两次(双指针各一次),总步数为两链表长度之和。 - 空间复杂度:O(1)。仅使用两个指针变量,无额外存储空间。
该方案通过双指针的交替遍历,既保证了时间效率,又避免了额外空间开销,是本题的最优解之一。