Loading...

一次遍历找到链表交点的优雅解法

在这里插入图片描述 需要注意的是,这里的"相交"是指两个链表在某个节点处合并,之后共享剩余的节点。

这道题的关键在于:如果两个链表相交,它们一定有共同的尾节点。

1.首先遍历两个链表,计算两个链表的长度差,然后找到各自的尾节点。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
ListNode a = h1, b = h2;
int diff = 0;
while (a.next != null) {
    a = a.next;
    diff++;
}
while (b.next != null) {
    b = b.next;
    diff--;
}
if (a != b) {
    return null;
}

用一个变量diff同时记录长度差。

遍历h1时diff++,遍历h2时diff–,最终diff就是两个链表的长度差。

遍历结束后,如果a != b,说明两个链表的尾节点不同,必然不相交。

2.让较长的链表先走若干步,消除长度差。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
if (diff >= 0) {
    a = h1;  // h1更长
    b = h2;
} else {
    a = h2;  // h2更长
    b = h1;
}
diff = Math.abs(diff);
while (diff-- != 0) {
    a = a.next;  // 长链表先走
}

3.两个指针距离各自链表尾部的距离相同,接下来同步前进,第一个相同的节点就是交点。

1
2
3
4
5
while (a != b) {
    a = a.next;
    b = b.next;
}
return a;

完整代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public static ListNode getIntersectionNode(ListNode h1,ListNode h2){
		if(h1==null||h2==null){
			return null;
		}
		ListNode a = h1,b=h2;
		int diff =0 ;
		//计算长度差,找到h1的尾节点
		while(a.next!=null){
			a=a.next;
			diff++;
		}

		//计算长度差,找到h2的尾节点
		while(b.next!=null){
			b= b.next;
			diff--;
		}

		//尾节点不同,不相交
		if(a!=b){
			return null;
		}
		//让a指向较长的链表,b指向较短的链表
		if(diff>=0){
			a=h1;
			b=h2;
		}else{
			a=h2;
			b=h1;
		}
		//长链表先走diff步
		diff=Math.abs(diff);
		while(diff--!=0){
			a=a.next;
		}

		//同步前进,找到交点
		while(a!=b){
			a=a.next;
			b=b.next;
		}
		return a;
	}
最后更新于 2026-04-05 17:35:33
Code Road Record