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,6,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,6,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 = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
Output: Reference of the node with value = 2
Input Explanation: The intersected node's value is 2 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [1,9,1,2,4]. From the head of B, it reads as [3,2,4]. There are 3 nodes before the intersected node in A; There are 1 node before the intersected node in B.
Example 3:
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.
Notes:
If the two linked lists have no intersection at all, return null.
The linked lists must retain their original structure after the function returns.
You may assume there are no cycles anywhere in the entire linked structure.
Each value on each linked list is in the range [1, 10^9].
Your code should preferably run in O(n) time and use only O(1) memory.
暴力法
会超时
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA and headB:
HeadB = headB
while headA:
while HeadB:
if headA != HeadB:
HeadB = HeadB.next
else:
return headA
headA = headA.next
HeadB = headB
哈希表法
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA and headB:
ASet = {headA}
while headA.next:
headA = headA.next
ASet.add(headA)
while headB:
if headB in ASet:
return headB
else:
headB = headB.next
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA and headB:
A_Hash_Table = {}
while headA:
A_Hash_Table[headA] = headA.next
headA = headA.next
while headB:
if headB in A_Hash_Table:
return headB
else:
headB = headB.next
双指针法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA and headB:
pointer_A = headA
pointer_B = headB
i = 1
while pointer_A != pointer_B:
if pointer_A.next:
pointer_A = pointer_A.next
else:
pointer_A = headB
i += 1
if i>2:
return None
if pointer_B.next:
pointer_B = pointer_B.next
else:
pointer_B = headA
return pointer_A
事实上,发现并不必去计算或者限制循环交替了几次,因为在不设置的情况下,即使第二次仍无相遇,这时候会在A、B指针都为None情况下跳出循环,而返回值自然也是None
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA and headB:
pointer_A = headA
pointer_B = headB
while pointer_A != pointer_B:
if pointer_A:
pointer_A = pointer_A.next
else:
pointer_A = headB
if pointer_B:
pointer_B = pointer_B.next
else:
pointer_B = headA
return pointer_A
# 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
"""
if headA and headB:
pointer_A = headA
pointer_B = headB
while pointer_A or pointer_B:
if not pointer_A:
pointer_A = headB
if not pointer_B:
pointer_B = headA
if pointer_A == pointer_B and not None:
return pointer_A
pointer_A, pointer_B = pointer_A.next, pointer_B.next