題目
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.