link: 相交链表
第一种:最巧妙的方法, 把两个链表加起来, A+B的长度和B+A的长度是一样的,同时遍历这两个相加后的链表,如果有交点,必然会某个位置他们相等,如果没有交点,最后也会相等,因为链表的尾部都是null
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode a = headA;
ListNode b = headB;
while(a != b){
if(a == null)
a = headB;
else
a = a.next;
if(b == null)
b = headA;
else
b = b.next;
}
return a;
}
第二种:我自己想出来的,计算两个链表的长度,同时看最后一个节点是否相等,若不相等,必然无交点,若相等就说明有交点。计算链表长度的插值,用一个快指针先走这个插值的步数,然后慢指针开始走,二者指向相同节点的位置就是交点
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA ==null || headB ==null) return null;
ListNode a = headA;
ListNode b = headB;
int cntA = 0;
while (a.next != null){
a = a.next;
cntA++;
}
int cntB = 0;
while (true){
if(b == null) return null;
if(b == a) break;
b = b.next;
cntB++;
}
a = headA;
b = headB;
if(cntA > cntB){//快指针先走长链表与短链表的插值
int cnt = 0;
while (cnt < (cntA-cntB)){
a = a.next;
cnt++;
}
}else{
int cnt = 0;
while (cnt < (cntB-cntA)){
b = b.next;
cnt++;
}
}
while(a != null && b != null){
if(a == b) return a;
a = a.next;
b = b.next;
}
return null;
}
第三种:可以过题,但是其实不符合要求的哈希法
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
HashMap<ListNode, Integer> hm = new HashMap<>();
ListNode a = headA;
while(a != null){
hm.put(a, 1);
a= a.next;
}
ListNode b = headB;
while(b != null){
if(hm.containsKey(b)){
return b;
}
b = b.next;
}
return null;
}