两种解法
首先需要知道一点
如果出现公共部分,很明显从第一个公共部分开始,后面都是相同的
所以要么有公共部分,要么两条链表就是组成Y型
- 1.使用set
- 就是先遍历一条链表,然后将它的节点都给存起来,那么再遍历另一条链表的时候第一次碰到在set中存在的节点很明显就是交点了
- 如果一直没有碰到交点,那么到最后出来循环返回null表示没有交点
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { if(pHead1==null||pHead2==null) return null; //用一个set来存一下pHead1遍历过的节点 HashSet<ListNode> set = new HashSet<>(); while(pHead1!=null){ set.add(pHead1); pHead1 = pHead1.next; } while(pHead2!=null){ if(set.contains(pHead2)){ return pHead2; } pHead2 = pHead2.next; } return null; }
- 2.双指针法
- 两条链表先遍历一遍,走到最后一个节点,同时记录这两条链表的长度len1,len2
- 如果他们的最后一个节点是不同的,很明显不相交,直接返回null
- 如果最后节点相同,那么如何找到交点?
- 先让长的链表先走|len1-len2|步
- 然后两个链表一起走肯定会在交点处相遇
- 两条链表先遍历一遍,走到最后一个节点,同时记录这两条链表的长度len1,len2
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { if(pHead1==null||pHead2==null) return null; ListNode t1 = pHead1; ListNode t2 = pHead2; int len1 = 1; int len2 = 1; while(t1.next!=null||t2.next!=null){ if(t1.next!=null){ t1 = t1.next; len1++; } if(t2.next!=null){ t2 = t2.next; len2++; } } if(t1!=t2) return null; //长的那个先走Math.abs(t1-t2)步 t1 = len1>len2?pHead1:pHead2; t2 = t1==pHead1?pHead2:pHead1;//t1指向长链表 for(int i = 0;i<Math.abs(len1-len2);i++){ t1 = t1.next; } //同时走,走到相交 while(t1!=t2){ t1 = t1.next; t2 = t2.next; } return t1; }