0
点赞
收藏
分享

微信扫一扫

【小Y学算法】⚡️每日LeetCode打卡⚡️——42. 相交链表

南陵王梁枫 2022-03-25 阅读 180




  • ​​????前言​​
  • ​​????原题样例:相交链表​​
  • ​​????C#方法:深度优先搜索​​
  • ​​????Java 方法一:哈希集合​​
  • ​​????Java 方法二:双指针​​
  • ​​????总结​​


【小Y学算法】⚡️每日LeetCode打卡⚡️——42. 相交链表_java

????前言

???? 算法题 ????


  • ???? 每天打卡一道算法题,既是一个学习过程,又是一个分享的过程????
  • ???? 提示:本专栏解题 编程语言一律使用 C# 和 Java 两种进行解题
  • ???? 要保持一个每天都在学习的状态,让我们一起努力成为算法大神吧????!
  • ???? 今天是力扣算法题持续打卡第42天????!


???? 算法题 ????

????原题样例:相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

图示两个链表在节点 c1 开始相交:

【小Y学算法】⚡️每日LeetCode打卡⚡️——42. 相交链表_算法_02

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

实例1

【小Y学算法】⚡️每日LeetCode打卡⚡️——42. 相交链表_算法_03

输入: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 个节点。

示例 2:

【小Y学算法】⚡️每日LeetCode打卡⚡️——42. 相交链表_链表_04

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A [0,9,1,2,4],链表 B [3,2,4]
A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例3

【小Y学算法】⚡️每日LeetCode打卡⚡️——42. 相交链表_leetcode_05

输入: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
  • listA 中节点数目为 m
  • listB 中节点数目为 n
  • 0 <= m, n <= 3 * 104
  • 1 <= Node.val <= 105
  • 0 <= skipA <= m
  • 0 <= skipB <= n
  • 如果 listA 和 listB 没有交点,intersectVal 为 0
  • 如果 listA 和 listB 有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]

????C#方法:深度优先搜索

判断两个链表是否相交,可以使用哈希集合存储链表节点。

首先遍历链表 headA,并将链表 headA 中的每个节点加入哈希集合中。然后遍历链表 headB,对于遍历到的每个节点,判断该节点是否在哈希集合中:

  • 如果当前节点不在哈希集合中,则继续遍历下一个节点;
  • 如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都在两个链表的相交部分,因此在链表 headB 中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点,返回该节点。

如果链表 headB 中的所有节点都不在哈希集合中,则两个链表不相交,返回 null。

思路解析

代码:

public class Solution {
public ListNode GetIntersectionNode(ListNode headA, ListNode headB) {
ISet<ListNode> visited = new HashSet<ListNode>();
ListNode temp = headA;
while (temp != null) {
visited.Add(temp);
temp = temp.next;
}
temp = headB;
while (temp != null) {
if (visited.Contains(temp)) {
return temp;
}
temp = temp.next;
}
return null;
}
}

执行结果

通过
执行用时:124 ms,在所有 C# 提交中击败了65.20%的用户
内存消耗:38.5 MB,在所有 C# 提交中击败了15.20%的用户

复杂度分析

时间复杂度:O( m+n ),其中 m  n 是分别是链表 headA  headB 的长度。需要遍历两个链表各一次。
空间复杂度:O(m),其中 m 是链表 headA 的长度。需要使用哈希集合存储链表 headA 中的全部节点。

????Java 方法一:哈希集合

思路解析

判断两个链表是否相交,可以使用哈希集合存储链表节点。

首先遍历链表 headA,并将链表 headA 中的每个节点加入哈希集合中。然后遍历链表 headB,对于遍历到的每个节点,判断该节点是否在哈希集合中:

  • 如果当前节点不在哈希集合中,则继续遍历下一个节点;
  • 如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都在两个链表的相交部分,因此在链表 headB 中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点,返回该节点。

如果链表 headB 中的所有节点都不在哈希集合中,则两个链表不相交,返回 null。

代码:

public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode> visited = new HashSet<ListNode>();
ListNode temp = headA;
while (temp != null) {
visited.add(temp);
temp = temp.next;
}
temp = headB;
while (temp != null) {
if (visited.contains(temp)) {
return temp;
}
temp = temp.next;
}
return null;
}
}

执行结果

通过
执行用时:7 ms,在所有 Java 提交中击败了22.83%的用户
内存消耗:42.3 MB,在所有 Java 提交中击败了6.96%的用户

复杂度分析

时间复杂度:O( m+n ),其中 m  n 是分别是链表 headA  headB 的长度。需要遍历两个链表各一次。
空间复杂度:O(m),其中 m 是链表 headA 的长度。需要使用哈希集合存储链表 headA 中的全部节点。

????Java 方法二:双指针

思路解析

【小Y学算法】⚡️每日LeetCode打卡⚡️——42. 相交链表_leetcode_06

代码:

public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode pA = headA, pB = headB;
while (pA != pB) {
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}

执行结果

通过
执行用时:1 ms,在所有 Java 提交中击败了100.00%的用户
内存消耗:41.2 MB,在所有 Java 提交中击败了59.13%的用户

复杂度分析

时间复杂度:O(m+n)
空间复杂度:O(1)

????总结

  • 今天是力扣算法题打卡的第四十二天!
  • 文章采用 ​​C#​​和 ​​Java​​ 两种编程语言进行解题
  • 一些方法也是参考力扣大神写的,也是边学习边分享,再次感谢算法大佬们
  • 那今天的算法题分享到此结束啦,明天再见!
    【小Y学算法】⚡️每日LeetCode打卡⚡️——42. 相交链表_链表_07


举报

相关推荐

0 条评论