2
2
3
3
import com .scuyjzh .leetcode .structure .ListNode ;
4
4
5
- import java .util .*;
6
-
7
5
/**
8
6
* 160. 相交链表
9
7
*
10
8
* 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表
11
9
* 相交的起始节点。如果两个链表不存在相交节点,返回 null 。
10
+ *
12
11
* 题目数据 保证 整个链式结构中不存在环。
13
- * 注意,函数返回结果后,链表必须 保持其原始结构 。
14
- * 进阶:你能否设计一个时间复杂度 O(m + n) 、仅用 O(1) 内存的解决方
15
- * 案?
12
+ *
13
+ * 进阶:你能否设计一个时间复杂度 O(m + n) 、仅用 O(1) 内存的解决方案?
16
14
*/
17
15
class Solution {
18
16
/**
19
- * 方法一:哈希集合
20
- */
21
- public ListNode getIntersectionNode1 (ListNode headA , ListNode headB ) {
22
- /*
23
- * 判断两个链表是否相交,可以使用哈希集合存储链表节点。
24
- *
25
- * 首先遍历链表 headA,并将链表 headA 中的每个节点加入哈希集合中。然后遍历链表 headB,对于遍历到的
26
- * 每个节点,判断该节点是否在哈希集合中:
27
- * • 如果当前节点不在哈希集合中,则继续遍历下一个节点;
28
- * • 如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都在两个链
29
- * 表的相交部分,因此在链表 headB 中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点,
30
- * 返回该节点。
31
- *
32
- * 如果链表 headB 中的所有节点都不在哈希集合中,则两个链表不相交,返回 null。
33
- */
34
- Set <ListNode > visited = new HashSet <>();
35
- ListNode temp = headA ;
36
- while (temp != null ) {
37
- visited .add (temp );
38
- temp = temp .next ;
39
- }
40
- temp = headB ;
41
- while (temp != null ) {
42
- if (visited .contains (temp )) {
43
- return temp ;
44
- }
45
- temp = temp .next ;
46
- }
47
- return null ;
48
- }
49
-
50
- /**
51
- * 方法二:双指针
17
+ * 方法:双指针
52
18
*/
53
- public ListNode getIntersectionNode2 (ListNode headA , ListNode headB ) {
54
- /*
55
- * pA 走过的路径为 A链 + B链,
56
- * pB 走过的路径为 B链 + A链。
57
- * pA 和 pB 走过的长度相同,都是 A链 和 B链 的长度之和。
58
- *
59
- * 即相当于将两个链表从尾端对齐,如果相交,则会提前在相交点相遇;
60
- * 如果没有相交点,则会在最后相遇。
61
- *
62
- * pA: 4->1->8->4->5->null->5->6->1->[8]->4->5->null
63
- * pB: 5->6->1->8->4->5->null->4->1->[8]->4->5->null
64
- */
19
+ public ListNode getIntersectionNode (ListNode headA , ListNode headB ) {
20
+ // 首先判断链表 headA 和 headB 是否为空,如果其中至少有一个链表为空,则两个链表一定不相交,返回 null
65
21
if (headA == null || headB == null ) {
66
22
return null ;
67
23
}
24
+ // 创建两个指针 pA 和 pB,初始时分别指向两个链表的头节点 headA 和 headB
68
25
ListNode pA = headA , pB = headB ;
26
+ // 然后将两个指针依次遍历两个链表的每个节点,每步操作需要同时更新指针 pA 和 pB
69
27
while (pA != pB ) {
28
+ // 如果指针 pA 不为空,则将指针 pA 移到下一个节点;
29
+ // 如果指针 pA 为空,则将指针 pA 移到链表 headB 的头节点
70
30
pA = pA == null ? headB : pA .next ;
31
+ // 如果指针 pB 不为空,则将指针 pB 移到下一个节点;
32
+ // 如果指针 pB 为空,则将指针 pB 移到链表 headA 的头节点
71
33
pB = pB == null ? headA : pB .next ;
72
34
}
35
+ // 当指针 pA 和 pB 指向同一个节点或者都为空时,返回它们指向的节点或者 null
73
36
return pA ;
74
37
}
75
38
@@ -87,7 +50,6 @@ public static void main(String[] args) {
87
50
headB .next .next = new ListNode (1 );
88
51
headB .next .next .next = intersectionNode ;
89
52
90
- System .out .println (ListNode .toString (new Solution ().getIntersectionNode1 (headA , headB )));
91
- System .out .println (ListNode .toString (new Solution ().getIntersectionNode2 (headA , headB )));
53
+ System .out .println (new Solution ().getIntersectionNode (headA , headB ).val );
92
54
}
93
55
}
0 commit comments