题目
Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
begin to intersect at node c1.
Example 1:
Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
Output: Reference of the node with value = 8
Input Explanation: The intersected node’s value is 8 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,0,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B.
Example 2:
Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
Output: null
Input Explanation: From the head of A, it reads as [2,6,4]. From the head of B, it reads as [1,5]. Since the two lists do not intersect, intersectVal must be 0, while skipA and skipB can be arbitrary values.
Explanation: The two lists do not intersect, so return null.
注意:
- 如果不相交,返回null
- 不能改变输入链表
- 你可以认为输入的链表中没有环路
- 你的代码应该尽可能的实现时间复杂度O(n)以及空间复杂度O(1)
解法
常规的解法
依次遍历链表A和B,用集合sa和sb记录见过的节点,并判断是否相交.此种算法时间复杂度为O(n),但是空间复杂度较高.代码如下:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
na, nb, ni = headA, headB, None
sa, sb = {na}, {nb}
while na or nb:
if na in sb:
ni = na
break
if nb in sa:
ni = nb
break
if na:
na = na.next
sa.add(na)
if nb:
nb = nb.next
sb.add(nb)
return ni
算法的结果如下:
Runtime: 188 ms, faster than 85.84% of Python online submissions for Intersection of Two Linked Lists.
Memory Usage: 42.9 MB, less than 5.33% of Python online submissions for Intersection of Two Linked Lists.
巧妙且应该掌握的解法
该解法由coordinate_blog进行了清晰的解释,我在这里记录一下.如下图,链表A和B都是由各自黑色的部分和共同的红色部分组成.
如果将链表拉直然后拼成A+B和B+A放在一起,就会成为下面这个样子:
最后的红色部分是对齐了的,所以我们就能在该出通过相等判断找到相交的位置.注意,没有相交的情况可以看做在节点None处(最末尾)相交了.代码如下:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
na, nb = headA, headB
while na != nb:
na = na.next if na else headB
nb = nb.next if nb else headA
return na
运行结果如下,好像并不是很优秀…:
Runtime: 184 ms, faster than 92.74% of Python online submissions for Intersection of Two Linked Lists.
Memory Usage: 41.8 MB, less than 37.33% of Python online submissions for Intersection of Two Linked Lists.