1. 程式人生 > >*160. Intersection of Two Linked Lists

*160. Intersection of Two Linked Lists

鏈表 分享 iteration null type span sam ack cycle

1. 原始題目

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 = 2, listA = [0,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 [0,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.
  • Your code should preferably run in O(n) time and use only O(1) memory.

2. 題目理解

就是找兩個鏈表的交叉結點。註意:空鏈表;不存在交叉點的鏈表

3. 解題

思路:用兩個棧:依次將鏈表a和b分別進棧。然後出棧時比較兩個元素是否相等。如果遇到不同的結點,那麽該結點的上一個結點就是交叉節點。

 1 # Definition for singly-linked list.
 2 # class ListNode(object):
 3 #     def __init__(self, x):
 4 #         self.val = x
 5 #         self.next = None
 6 
 7 class Solution(object):
 8     def getIntersectionNode(self, headA, headB):
 9         """
10         :type head1, head1: ListNode
11         :rtype: ListNode
12         """
13         if headA is None or headB is None:     # 空鏈表處理
14             return None
15         results = None
16         stacka = []
17         stackb = []
18         a = headA
19         b = headB
20         while(a):                              # a進棧  
21             stacka.append(a)
22             a = a.next
23         while(b):                              # b進棧  
24             stackb.append(b)
25             b = b.next
26         
27         i = -1
28         if stacka[i]!=stackb[i]:               # 頭元素都不相等肯定沒有交叉點
29             return None
30         while (stacka[i]==stackb[i]):
31                 i = i-1
32                 if abs(i)>len(stacka) or abs(i)>len(stackb):
33                     break
34         results = stacka[i+1]                  # 返回上一個結點
35         return results

當然我在Leetcode裏發現了更簡潔,漂亮的解法。如下:

# the idea is if you switch head, the possible difference between length would be countered. 
# On the second traversal, they either hit or miss. 
# if they meet, pa or pb would be the node we are looking for, 
# if they didn‘t meet, they will hit the end at the same iteration, pa == pb == None, return either one of them is the same,None

即遍歷到鏈表尾後就交換頭結點繼續遍歷。在第二次反轉時就會相遇或者錯過。如果相遇那麽該結點就是交叉點,錯過就是不存在交叉點

 1 class Solution:
 2     # @param two ListNodes
 3     # @return the intersected ListNode
 4     def getIntersectionNode(self, headA, headB):
 5         if headA is None or headB is None:
 6             return None
 7 
 8         pa = headA # 2 pointers
 9         pb = headB
10 
11         while pa is not pb:
12             # if either pointer hits the end, switch head and continue the second traversal, 
13             # if not hit the end, just move on to next
14             pa = headB if pa is None else pa.next   # 走到該鏈表末尾後下一步走另個鏈表開頭
15             pb = headA if pb is None else pb.next
16 
17         return pa # only 2 ways to get out of the loop, they meet or the both hit the end=None

*160. Intersection of Two Linked Lists