题目描述
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
来源:力扣(LeetCode)
链接:LeetCode
题目分析
(1)有一种比较浪漫的解法,就是A走完自己的路,然后走B的路,B走完自己的路后,走A的路,这样两个有交集并互相牵挂的A和B一定会在一起;
(2)假设相交之前的那部分,A的长度是a,B的长度是b,相交之后的那部分长度是公共部分,长度为c;
(3)当A走完自己的部分再走过B的前半部分,长度为a+c+b;
(4)当B走完自己的部分再走过A的前半部分,长度为b+c+a;
(5)此时两者就相遇了,这就是相交链表的求法,当然了不相交的情况也是成立的,也就是a+b=b+a。
(6)第二种解法是用HashSet,由于相交后结点是唯一的,即当把A的所有结点放入集合后,遍历B中结点看是否已存在于集合,但是此处的判断,比较的不仅仅是结点值,而是结点本身,因此结点若存在于集合,就一定是第一个相交的结点。
代码
/**
先别慌,时间会给我们想要的一切,我走你走过的路,
你走我走过的路,我们最终会在一起,同生共死
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null||headB==null){
return null;
}
ListNode linkA=headA;
ListNode linkB=headB;
while(linkA!=linkB){
linkA=linkA==null?headB:linkA.next;
linkB=linkB==null?headA:linkB.next;
}
return linkA;
}
}
//用HashSet
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB){
if(headA==null||headB==null){
return null;
}
Set<ListNode> set = new HashSet<ListNode>();
ListNode tmp=headA;
while(tmp!=null){
set.add(tmp);
tmp=tmp.next;
}
tmp=headB;
while(tmp!=null){
if(set.contains(tmp)){
//直接找到结点就可以的原因是,相交链表从交点处,
//后续结点地址相同,而此处比较的也是地址,并不仅仅是值
return tmp;
}
tmp=tmp.next;
}
return null;
}
}