核心思想:HashSet/双指针
思路:
我的思路就不说了,正常人都能想到。
官方思路:
只有当链表headA 和headB 都不为空时,两个链表才可能相交。因此首先判断链headA 和 headB 是否为空,如果其中至少有一个链表为空,则两个链表一定不相交,返回null。
当链表headA 和headB 都不为空时,创建两个指针la和lb,初始时分别指向两个链表的头节点 headA 和 headB,然后将两个指针依次遍历两个链表的每个节点。具体做法如下:
每步操作需要同时更新指针la和lb。
如果指针la 不为空,则将指针la移到下一个节点;如果指针lb不为空,则将指针lb移到下一个节点。
如果指针la为空,则将指针la移到链表headB 的头节点;如果指针lb 为空,则将指针lb移到链表 headA 的头节点。
当指针la和lb 指向同一个节点或者都为空时,返回它们指向的节点或者null。
为什么这么做?
证明:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/solution/xiang-jiao-lian-biao-by-leetcode-solutio-a8jn/
我的笨比方法:
时间复杂度O(m+n)
空间复杂度O(m)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
HashSet<ListNode> hashset = new HashSet<>();
while(headA != null){
hashset.add(headA);
headA = headA.next;
}
while(headB != null){
if(hashset.contains(headB)){
return headB;
}
headB = headB.next;
}
return null;
}
}
官方题解:
时间复杂度O(m+n)
空间复杂度O(1)
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null){
return null;
}
ListNode la = headA;
ListNode lb = headB;
while(la != lb){
if(la == null){
la = headB;
}else{
la = la.next;
}
if(lb == null){
lb = headA;
}else{
lb = lb.next;
}
}
return la;
}
}