这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战
一、了解题目
附上原题链接:160. 相交链表
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
二、题解分析
判断两个链表是否相交,那么我们可以使用哈希集合来存储链表节点。具体步骤如下:
- 首先遍历链表
headA,并将链表headA中的每个节点加入哈希集合中; - 然后遍历链表
headB,对于遍历到的每个节点,判断该节点是否在哈希集合中: - 如果当前节点不在哈希集合中,则继续遍历下一个节点;
- 如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都在两个链表的相交部分,因此在链表
headB中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点,返回该节点; - 如果链表
headB中的所有节点都不在哈希集合中,则两个链表不相交,返回null。
三、代码实现
依据上面的题解,我们将用 js 来实现这道题。具体实现代码如下:
/**
* @description leetcode 160.相交链表
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function (headA, headB) {
// 1.定义一个空集合,存放链表A中的节点
const visited = new Set();
// 2.定义temp指针,指向headA
let temp = headA;
// 3.不断循环temp指针,并将temp指针指向链表的下一个节点,直到temp指针为空时再结束循环
while (temp !== null) {
visited.add(temp);
temp = temp.next;
}
// 4.将temp指针指向链表B
temp = headB;
// 5.不断循环链表B
while (temp !== null) {
// 5.1 判断链表B的节点是否有与链表A相同的,如果有,则返回
if (visited.has(temp)) {
return temp;
}
temp = temp.next;
}
// 6.如果找不到相同的节点,则返回null
return null;
};
四、复杂度分析
最后,我们来做下上述题目的复杂度分析。具体如下:
时间复杂度: O(m+n) ,其中 m 和 n 是分别是链表 headA 和 headB 的长度。需要遍历两个链表各一次。
空间复杂度: O(m) ,其中 m 是链表 headA 的长度。需要使用哈希集合存储链表 headA 中的全部节点。
思路来源:相交链表
看到这里,可以再尝试着设计一个时间复杂度为 O(n) 、 空间复杂度为 O(1) 的解决方案。如果有思路,评论区留下你的答案呀~
以上就是关于相交链表的题解,不知道对小伙伴们是否有帮助呢?
我们下期见👋👋👋