1.思路:开始想的是分别用两个hashSet保存两个两个链表的元素,最后返回元素的交集即可。很明显这是错误的想法,题目要求是返回相交的节点。所以,正确的做法是保存一个链表的节点,遍历另外一个链表,遇到元素相同的节点停止,返回该节点即可。
2.代码:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode pa = headA;
ListNode pb = headB;
Set<ListNode> setA = new HashSet<ListNode>();
while (pa != null){
setA.add(pa);
pa = pa.next;
}
while (pb != null){
if(setA.contains(pb))return pb;
pb = pb.next;
}
return null;
}
}
3.复杂度分析:l42时间复杂度为o(n) + o(n) = o(n),160时间复杂度为o(m+n) 。why?142时间主要消耗在了寻找相遇点和入环点,寻找走的距离没有超过链表长度,所以是0(n)。而相交链表是实打实的要走完链表,所以是0(m+n)。
方法二双指针。
思路:假设如果相交,则相交前的长度链表A为a,链表B的长度为b,相交长度为c。怎么找出相交点呢,当两个指针都走了a + b +c时,必然相交。每次pa和pb都走一步,如果pa为空,则从链表B开始走,如果pa为空,则从链表B开始走,直到pa==pb。
代码:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null)return null;
ListNode pa = headA;
ListNode pb = headB;
while (pa != null || pb != null){
if(pa == pb)return pa;
if(pa.next == null){
pa = headB;
}else {
pa = pa.next;
}
if(pb.next == null){
pb = headA;
}else {
pb = pb.next;
}
}
return null;
}
}
复杂度分析:时间0(m+n),空间为0(1),使用哈希表为0(m)