题目:Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
begin to intersect at node c1.
【note】
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.
Your code should preferably run in O(n) time and use only O(1) memory.
题目分析:
第一版:一拿到题目,我对题目的分析,以例子来进行分析,断开a1与a2的连接关系,然后使a1指向b1,从b1如果能遍历到a2,则说明a2在相交的链上,也就是在相同的子链上。依次处理每个A链上的结点,最终得到需要的结果。
对处理的结果是超时,,这个算法的时间复杂度都是O(n^2)了吧。
# 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 == None or headB == None:
return None
node1 = headA
node2 = node1.next
while node2:
node1.next = headB
if self.isnext(headB, node2):
node1.next = node2
return node2
else:
node1.next = node2
node1 = node2
node2 = node1.next
return None
def isnext(self, headB, next_n):
node = headB
while node:
if node == next_n:
return True
return False
第二种思路:成立的条件在于二个链表之前有不同的地方,也就是a1,b1应该是不为0的,在这种条件下,我们将B链表的最后节点指向A节点,这样可以利用龟兔赛跑算法来求解,也就是Floyd判圈算法,还可以得到圈的起点,也就是相交点。对于二个链表从头结点开始可能就与另一个链表相同的情形下,是不能利用判圈算法来进行判断的,这个时候需要特殊的进行判断。
# 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 == None or headB == None:
return None
node = headB
nodea = headA
while node:
if node == headA:
return headA
if node.next == None:
while nodea:
if nodea == headB:
return headB
else:
nodea = nodea.next
node.next = headA
break
else:
node = node.next
node = self.iscycle(headB)
nodeB = headB
while nodeB.next:
if nodeB.next == headA:
nodeB.next = None
else:
nodeB = nodeB.next
return node
def iscycle(self, head):
if head.next == None or head.next.next == None:
return None
fast = head.next.next
slow = head.next
while fast:
if slow == fast:
slow = head
while True:
if slow == fast:
return slow
else:
slow = slow.next
fast = fast.next
else:
try:
fast = fast.next.next
slow = slow.next
except:
return None
return None
好的,终于把这个问题解决了,看一下大佬们的思路,好像是很简单的说。。
class Solution:
# @param two ListNodes
# @return the intersected ListNode
def getIntersectionNode(self, headA, headB):
if headA is None or headB is None:
return None
pa = headA # 2 pointers
pb = headB
while pa is not pb:
# if either pointer hits the end, switch head and continue the second traversal,
# if not hit the end, just move on to next
pa = headB if pa is None else pa.next
pb = headA if pb is None else pb.next
return pa # only 2 ways to get out of the loop, they meet or the both hit the end=None