方法一:哈希
package com.company.linked;
import java.util.HashSet;
import java.util.Set;
public class Solution3 {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode> noRepeatSet = new HashSet<>();
while (headA != null || headB != null) {
if (headA != null) {
if (noRepeatSet.contains(headA)) {
return headA;
}
noRepeatSet.add(headA);
headA = headA.next;
}
if (headB != null) {
if (noRepeatSet.contains(headB)) {
return headB;
}
noRepeatSet.add(headB);
headB = headB.next;
}
}
return null;
}
}
方法二:双指针
- 求出两个链表的长度
- 将更长的链表长的几个节点忽略,然后两个链表逐步遍历,遇到相等节点则表示相交
package com.company.linked;
public class Solution3_1 {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode pA = headA;
ListNode pB = headB;
int aCount = 0, bCount = 0;
while (pA != null) {
aCount++;
pA = pA.next;
}
pA = headA;
while (pB != null) {
bCount++;
pB = pB.next;
}
pB = headB;
if (aCount > bCount) {
for (int i = 0; i < aCount - bCount; i++) {
pA = pA.next;
}
while (pA != null && pB != null) {
if (pA == pB) {
return pA;
}
pA = pA.next;
pB = pB.next;
}
} else if (aCount < bCount) {
for (int i = 0; i < bCount - aCount; i++) {
pB = pB.next;
}
while (pA != null && pB != null) {
if (pA == pB) {
return pA;
}
pA = pA.next;
pB = pB.next;
}
} else {
while (pA != null && pB != null) {
if (pA == pB) {
return pA;
}
pA = pA.next;
pB = pB.next;
}
}
return null;
}
}
方法三:双指针
- 两个链表逐个遍历比较
- 只要有一个节点先等于null,即先走到尾部,则将当前遍历指针替换成另外一个链表的头;
- 这样循环往复两个指针一定会相遇,因为则将当前遍历指针替换成另外一个链表的头节点可以类似于人工加了一个环,然后两个一定会相遇
package com.company.linked;
public class Solution3_2 {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode pA = headA, pB = headB;
while (pA != pB) {
if (pA == null) {
pA = headB;
} else {
pA = pA.next;
}
if (pB == null) {
pB = headA;
} else {
pB = pB.next;
}
}
return pA;
}
}