462. 找出两个链表的第一个公共节点

问题描述
输入两个链表 , 找出它们的第一个公共节点 。
如下面的两个链表:
462. 找出两个链表的第一个公共节点文章插图
在节点 c1 开始相交 。
示例 1:
462. 找出两个链表的第一个公共节点文章插图
输入:intersectVal = 8,
listA = [4,1,8,4,5],
listB = [5,0,1,8,4,5],
skipA = 2, skipB = 3
输出:Reference of the node with value = http://kandian.youth.cn/index/8
输入解释:相交节点的值为 8 (注意 , 如果两个列表相交则不能为 0) 。 从各自的表头开始算起 , 链表 A 为 [4,1,8,4,5] , 链表 B为 [5,0,1,8,4,5] 。 在 A 中 , 相交节点前有 2 个节点;在 B 中 , 相交节点前有 3 个节点 。
示例 2:
462. 找出两个链表的第一个公共节点文章插图
输入:intersectVal = 2,
listA = [0,9,1,2,4],
listB = [3,2,4],
skipA = 3, skipB = 1
输出:Reference of the node with value = http://kandian.youth.cn/index/2
输入解释:相交节点的值为 2 (注意 , 如果两个列表相交则不能为 0) 。 从各自的表头开始算起 , 链表 A 为 [0,9,1,2,4] , 链表 B为 [3,2,4] 。 在 A 中 , 相交节点前有 3 个节点;在 B 中 , 相交节点前有 1 个节点 。
示例 3:
462. 找出两个链表的第一个公共节点文章插图
输入:intersectVal = 0,
listA = [2,6,4],
listB = [1,5],
skipA = 3, skipB = 2
输出:null
输入解释:从各自的表头开始算起 , 链表 A 为 [2,6,4] , 链表 B 为 [1,5] 。 由于这两个链表不相交 , 所以 intersectVal必须为 0 , 而 skipA 和 skipB 可以是任意值 。
解释:这两个链表不相交 , 因此返回 null 。
注意:

  1. 如果两个链表没有交点 , 返回 null.
  2. 在返回结果后 , 两个链表仍须保持原有的结构 。
  3. 可假定整个链表结构中没有循环 。
  4. 程序尽量满足 O(n) 时间复杂度 , 且仅用 O(1) 内存 。
通过集合set解决
【462. 找出两个链表的第一个公共节点】上面说了一大堆 , 其实就是判断两个链表是否相交 , 如果相交就返回他们的相交的交点 , 如果不相交就返回null 。
做这题最容易想到的一种解决方式就是先把第一个链表的节点全部存放到集合set中 , 然后遍历第二个链表的每一个节点 , 判断在集合set中是否存在 , 如果存在就直接返回这个存在的结点 。 如果遍历完了 , 在集合set中还没找到 , 说明他们没有相交 , 直接返回null即可 , 原理比较简单 , 直接看下代码
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {//创建集合setSet set = new HashSet<>();//先把链表A的结点全部存放到集合set中while (headA != null) {set.add(headA);headA = headA.next;}//然后访问链表B的结点 , 判断集合中是否包含链表B的结点 , 如果包含就直接返回while (headB != null) {if (set.contains(headB))return headB;headB = headB.next;}//如果集合set不包含链表B的任何一个结点 , 说明他们没有交点 , 直接返回nullreturn null;}123456789101112131415161718先统计两个链表的长度
还可以先统计两个链表的长度 , 如果两个链表的长度不一样 , 就让链表长的先走 , 直到两个链表长度一样 , 这个时候两个链表再同时每次往后移一步 , 看节点是否一样 , 如果有相等的 , 说明这个相等的节点就是两链表的交点 , 否则如果走完了还没有找到相等的节点 , 说明他们没有交点 , 直接返回null即可 , 来画个图看一下 。


推荐阅读