问题描述
输入两个链表 , 找出它们的第一个公共节点 。
如下面的两个链表:
![找出两个链表的第一个公共节点](http://img.jiangsulong.com/220422/1R6393M2-0.jpg)
文章插图
在节点 c1 开始相交 。
示例 1:
![找出两个链表的第一个公共节点](http://img.jiangsulong.com/220422/1R63912H-1.jpg)
文章插图
输入: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 = https://www.isolves.com/it/cxkf/sf/2020-10-19/8
输入解释:相交节点的值为 8 (注意 , 如果两个列表相交则不能为 0) 。从各自的表头开始算起 , 链表 A 为 [4,1,8,4,5] , 链表 B
为 [5,0,1,8,4,5] 。在 A 中 , 相交节点前有 2 个节点;在 B 中 , 相交节点前有 3 个节点 。
【找出两个链表的第一个公共节点】示例 2:
![找出两个链表的第一个公共节点](http://img.jiangsulong.com/220422/1R6394312-2.jpg)
文章插图
输入:intersectVal = 2,
listA = [0,9,1,2,4],
listB = [3,2,4],
skipA = 3, skipB = 1
输出:Reference of the node with value = https://www.isolves.com/it/cxkf/sf/2020-10-19/2
输入解释:相交节点的值为 2 (注意 , 如果两个列表相交则不能为 0) 。从各自的表头开始算起 , 链表 A 为 [0,9,1,2,4] , 链表 B
为 [3,2,4] 。在 A 中 , 相交节点前有 3 个节点;在 B 中 , 相交节点前有 1 个节点 。
示例 3:
![找出两个链表的第一个公共节点](http://img.jiangsulong.com/220422/1R6394F0-3.jpg)
文章插图
输入: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 。
注意:
- 如果两个链表没有交点 , 返回 null.
- 在返回结果后 , 两个链表仍须保持原有的结构 。
- 可假定整个链表结构中没有循环 。
- 程序尽量满足 O(n) 时间复杂度 , 且仅用 O(1) 内存 。
通过集合set解决
上面说了一大堆 , 其实就是判断两个链表是否相交 , 如果相交就返回他们的相交的交点 , 如果不相交就返回null 。
做这题最容易想到的一种解决方式就是先把第一个链表的节点全部存放到集合set中 , 然后遍历第二个链表的每一个节点 , 判断在集合set中是否存在 , 如果存在就直接返回这个存在的结点 。如果遍历完了 , 在集合set中还没找到 , 说明他们没有相交 , 直接返回null即可 , 原理比较简单 , 直接看下代码
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {//创建集合setSet<ListNode> 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即可 , 来画个图看一下 。
![找出两个链表的第一个公共节点](http://img.jiangsulong.com/220422/1R639C46-4.jpg)
文章插图
最后再来看下代码
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {//统计链表A和链表B的长度int lenA = length(headA), lenB = length(headB);//如果节点长度不一样 , 节点多的先走 , 直到他们的长度一样为止while (lenA != lenB) {if (lenA > lenB) {//如果链表A长 , 那么链表A先走headA = headA.next;lenA--;} else {//如果链表B长 , 那么链表B先走headB = headB.next;lenB--;}}//然后开始比较 , 如果他俩不相等就一直往下走while (headA != headB) {headA = headA.next;headB = headB.next;}//走到最后 , 最终会有两种可能 , 一种是headA为空 , //也就是说他们俩不相交 。还有一种可能就是headA//不为空 , 也就是说headA就是他们的交点return headA;}//统计链表的长度private int length(ListNode node) {int length = 0;while (node != null) {node = node.next;length++;}return length;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 两个多月的泰迪怎么养 两个月的泰迪怎么养应该注意什么
- 五个月的金毛一天吃多少狗粮 两个月金毛一天吃多少狗粮
- 两个月的金吉拉怎么喂养 金吉拉好养吗?金吉拉猫的饲养方法
- 打印机不工作了?帮你找出背后原因
- PC电脑|Win10赶紧关掉这两个设置:以免电脑不到一年就“报废”
- excel中怎样把两个单元格的内容合并在一个单元格里?excell怎么把两个单元格内容合并到一个单元格?
- 詹姆斯一次得分王?两场36分23板8帽!火箭两个首轮换来内线未来?
- 海底捞为什么有清水锅 海底捞两个白水煮什么
- 马桶几个排污口好 马桶有两个排污口好还是一个好
- 七道经典的关于链表的笔试题目