题目
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:

在节点 c1 开始相交。
示例 1:
输入: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 = 8
输入解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists
分析
有几种方式,比较容易想到是当然是暴力法了。
- 第一种方式,暴力法,a不动,b动;a动一下,b动全部。挨个比较O(N2)的解法
- 第二种方式,hashmap解法,循环一遍a链表,将其加入到hashmap里。然后在循环b链表,挨个检查,是否有在map里。O(M+N)的时间复杂度,O(N)的空间复杂度。
- 第三种方式,先行法,A和B相交,其实相交的后半段是一样长的,不同的就是前半段。那么如果我们能让A和B通过移动其中的长的,将其向前先走几步。如图中B比A长1个节点,让B先走一步,然后A和B一块走,就能一起到达相交节点。如果没有相交,则走到头就会发现了。
- 第四种方式,双指针法,与上个检测环的交点类似,如何让A和B弥补长度上的差距呢?让A走完再走B的开头走,B走完再走A的开头走,这样A和B的移动步数就都是A+B里,如果有交点,就会一起到达了。
解法
以下是双指针解法。第三种的先行法,如果在链表有长度时候,将只需要O(N)就能判定,而双指针其实是O(2N)。
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
if headA == nil || headB == nil {
return nil
}
a, b := headA, headB
for a != b {
if a == nil {
a = headB
} else {
a = a.Next
}
if b == nil {
b = headA
} else {
b = b.Next
}
}
return a
}
本文探讨了在两个单链表中寻找相交起始节点的四种方法:暴力法、hashmap解法、先行法及双指针法,并详细解析了双指针法的实现过程。
1647

被折叠的 条评论
为什么被折叠?



