160. 相交链表
题目描述
哈希
- 将
h
e
a
d
A
headA
headA 中所有节点放入
set
中; - 然后,检查
h
e
a
d
B
headB
headB 中节点是否出现在
h
e
a
d
A
headA
headA 中:
- 若出现,则说明 当前节点为“交点”;
- 若 h e a d B headB headB 中所有节点均未在 set 中出现,说明 “无交点”
/**
* 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 p = headA;
ListNode q = headB;
Set<ListNode> setA = new HashSet<>();
while (p != null) {
setA.add(p);
p = p.next;
}
while (q != null) {
if (setA.contains(q)) {
return q;
}
q = q.next;
}
return null;
}
}
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
双指针
- 先求
h
e
a
d
A
headA
headA 和
h
e
a
d
B
headB
headB 的长度,记为
l
e
n
A
lenA
lenA、
l
e
n
B
lenB
lenB;
保证 h e a d A headA headA 是那个 “短” 的链表;否则,交换二者 - 然后,将两个链表的末尾对齐
即,将 q = h e a d B q = headB q=headB 向后移 l e n B − l e n A lenB - lenA lenB−lenA 个节点 - 链表
h
e
a
d
B
headB
headB 从
q
q
q 开始、链表
h
e
a
d
A
headA
headA 从
p
=
h
e
a
d
A
p = headA
p=headA,同时后移:
- 如果 q = = p q == p q==p,则说明当前节点为 “交点”;
- 如果 q 和 p 移动到 null,则说明 “无交点”
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lenA = 0;
int lenB = 0;
ListNode p = headA;
ListNode q = headB;
// 求 headA 长度
while (p != null) {
lenA++;
p = p.next;
}
// 求 headB 长度
while (q != null) {
lenB++;
q = q.next;
}
// 保证 headA 链表是长度短的那个
if (lenA > lenB) {
// 交换
int temp1 = lenA;
lenA = lenB;
lenB = temp1;
ListNode temp2 = headA;
headA = headB;
headB = temp2;
}
p = headA;
q = headB;
// 将 headB 向后移 lenB - lenA 个节点,保证 2 个链表头结点对齐
int i = 0;
while (i++ < (lenB - lenA)) {
q = q.next;
}
// 此时,二者末尾节点对齐。二者从头开始,同时后移
while (p != null) {
if (p == q) {
return p;
}
p = p.next;
q = q.next;
}
return null;
}
}
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)