1. 程式人生 > >LeetCode Intersection of Two Linked List

LeetCode Intersection of Two Linked List

Problem

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.

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. Your code should preferably run in O(n) time and use only O(1) memory.

即找到兩個連結串列相交的第一個元素。要求不改變連結串列結構,O(n)時間, O(1)記憶體

Python 實現


# 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. # # # 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. # Your code should preferably run in O(n) time and use only O(1) memory. # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None # author li.hzh class Solution(object): def getIntersectionNode(self, headA, headB): """ :type head1, head1: ListNode :rtype: ListNode """ if not headA or not headB: return None count_a = count_b = 1 point_a = headA point_b = headB while point_a.next is not None: point_a = point_a.next count_a += 1 while point_b.next is not None: point_b = point_b.next count_b += 1 sub_num = 0 long = short = None if count_a >= count_b: sub_num = count_a - count_b long = headA short = headB else: sub_num = count_b - count_a long = headB short = headA for i in range(sub_num): long = long.next while long is not short: long = long.next short = short.next return long def getIntersectionNode_II(self, headA, headB): """ :type head1, head1: ListNode :rtype: ListNode """ # 考慮一個有趣的事實,設連結串列A = a + c(公共部分),B = b + c(公共部分) # 那麼如果AB相接,到達c需要a + c + b步,同樣BA相接,需要b + c + a 步,二者相等,因此有程式碼: point_a, point_b = headA, headB if not point_a or not point_b: return None while point_a is not point_b: point_a = point_a.next if point_a is not None else headB point_b = point_b.next if point_b is not None else headA return point_a

分析

這裡我做了兩個實現,第一個是比較直白的。就是先計算兩個連結串列的長短,去掉長出的部分,剩下一樣長。然後兩個指標開始遍歷連結串列,找到相等的元素即可。

第二個實現的的原理已經寫在註釋上了,其實開始我就考慮首尾相接的解法。不過愚蠢的當環來處理,即對映到Linked List CycleII那道題上,時間超時了。一道Easy題,怎麼可能會那麼複雜。改進後,好多了。