1.题目
2.解法
-
暴力解法
解题思路:类似于两个数组的嵌套循环,找到公共的节点。
代码实现:
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { ListNode curA = headA, curB = headB; //两层循环 while(curA != null){ while(curB != null){ //找到相同节点,并返回该节点 if(curA == curB){ return curB; } curB = curB.next; } curA = curA.next; //注意这里需要将curB复位到headB curB = headB; } return null; } }
执行结果:
时间复杂度:O(n * m)
空间复杂度:O(1)
-
哈希表
解题思路:创建哈希表,将headA放入哈希表中,在哈希表中查找与headB公共的headA节点。
代码实现:
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { //创建HashMap,key为ListNode类,value为Boolean型 HashMap<ListNode, Boolean> map = new HashMap<ListNode, Boolean>(); ListNode curA = headA; ListNode curB = headB; //遍历链表A并存储 while(curA != null){ map.put(curA, true); curA = curA.next; } //在哈希表中查找公共节点 while(curB != null){ if(map.containsKey(curB)){ return curB; } curB = curB.next; } return null; } }
执行结果:
时间复杂度:O(n)空间复杂度:O(n)
-
快慢指针
解题思路:计算两链表节点个数之差n,将长链表指针右移n步,然后两链表同时向后查找公共节点。
代码实现:
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if(headA == null || headB == null) return null; int n = 0; ListNode curA = headA, curB = headB; //计数器计量链表A长度 while(curA.next != null){ curA = curA.next; n++; } //计数器累减计算A、B两表长度差 while(curB.next != null){ curB = curB.next; n--; } //如果A、B链表尾结点不相等,说明不存在公共节点 if(curA != curB) return null; curA = n > 0 ? headA : headB; curB = curA == headA ? headB : headA; //计数器可能为负值,需要取绝对值! n = Math.abs(n); //长链表指针右移n步 while(n > 0){ curA = curA.next; n--; } //两表同时遍历 while(curA != curB){ curA = curA.next; curB = curB.next; } return curA; } }
执行结果:
时间复杂度:O(n+m)
空间复杂度:O(1)
-
双指针(最浪漫的相遇)
解题思路:链表A的指针遍历完链表A后,接着遍历链表B;链表B的指针遍历完链表B后,接着遍历链表A;若存在公共节点,则两个指针相遇的时候,即为公共节点所在。
代码实现:
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { ListNode h1 = headA, h2 = headB; while(h1 != h2){ h1 = h1 == null ? headB : h1.next; h2 = h2 == null ? headA : h2.next; } return h1; } }
执行结果:
时间复杂度:O(n+m)
空间复杂度:O(1)