1. 程式人生 > 實用技巧 >兩個連結串列的第一個公共節點(Python and C++解法)

兩個連結串列的第一個公共節點(Python and C++解法)

題目:

輸入兩個連結串列,找出它們的第一個公共節點。

如下面的兩個連結串列:

在節點 c1 開始相交。

示例 1:

輸入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
輸出:Reference of the node with value = 8
輸入解釋:相交節點的值為 8 (注意,如果兩個列表相交則不能為 0)。從各自的表頭開始算起,連結串列 A 為 [4,1,8,4,5],連結串列 B 為 [5,0,1,8,4,5]。在 A 中,相交節點前有 2 個節點;在 B 中,相交節點前有 3 個節點。

示例2:

輸入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
輸出:null
輸入解釋:從各自的表頭開始算起,連結串列 A 為 [2,6,4],連結串列 B 為 [1,5]。由於這兩個連結串列不相交,所以 intersectVal 必須為 0,而 skipA 和 skipB 可以是任意值。
解釋:這兩個連結串列不相交,因此返回 null。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof

思路:

Python解法思路:

  第一次遍歷首先得到兩個連結串列的長度,算出長度差。

  讓較長的連結串列先走若干步,然後同步往後遍歷,找到的第一個公共點就符合要求。

C++解法思路:

  分別讓兩個連結串列的節點入棧,此時連結串列的末尾處於棧頂。接下來分別比較棧頂節點是否相同,如果相同則同時彈出,繼續比較下一次的棧頂節點,直至最後一對相等的棧頂節點。

注意:比較是否相等時應當比較節點,不應該比較節點的值。

Python解法:

 1 class ListNode:
 2     def __init__(self, x):
 3         self.val = x
 4         self.next = None
5 6 class Solution: 7 def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: 8 listALen = self.getListLen(headA) # 連結串列A的長度 9 listBLen = self.getListLen(headB) # 連結串列B的長度 10 longListHead = headA # 先假設連結串列A比較長 11 shortListHead = headB 12 if (listALen < listBLen): # 如果假設不成立,將連結串列B作為為較長的連結串列處理 13 longListHead = headB 14 shortListHead = headA 15 listLenDiff = abs(listALen - listBLen) 16 17 while listLenDiff: 18 longListHead = longListHead.next # 較長的節點先走幾步 19 listLenDiff -= 1 20 while longListHead is not None and shortListHead is not None and longListHead != shortListHead: # 找公共節點 21 longListHead = longListHead.next 22 shortListHead = shortListHead.next 23 return longListHead 24 25 def getListLen(self, theHead): # 計算連結串列長度 26 count = 0 27 while theHead is not None: 28 theHead = theHead.next 29 count += 1 30 return count

C++解法:

 1 struct ListNode {
 2      int val;
 3      ListNode *next;
 4      ListNode(int x) : val(x), next(NULL) {}
 5  };
 6  
 7 class Solution {
 8 public:
 9     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
10         stack<ListNode*> stackA;
11         stack<ListNode*> stackB;
12         ListNode *tempHeadA = headA;
13         ListNode *tempHeadB = headB;
14         while (tempHeadA != NULL) {  // 將連結串列A的節點入棧
15             stackA.push(tempHeadA);
16             tempHeadA = tempHeadA->next;
17         }
18         while (tempHeadB != NULL) {  // 將連結串列B的節點入棧
19             stackB.push(tempHeadB);
20             tempHeadB = tempHeadB->next;
21         }
22 
23         ListNode *tempNodeA, *tempNodeB;
24         while (!stackA.empty() && !stackB.empty()) {  // 節點依次從棧頂出棧,即從連結串列尾部向前比較
25             tempNodeA = stackA.top();
26             tempNodeB = stackB.top();
27             if (tempNodeA == tempNodeB) {
28                 stackA.pop();
29                 stackB.pop();
30                 // 如果剛出棧的節點相等,且此時有棧變空
31                 if (stackA.empty() || stackB.empty())
32                     return tempNodeA;
33                 if ((!stackA.empty() && !stackB.empty()) && (stackA.top() != stackB.top()))  // 如果兩個棧都未變空的情況下,下一對棧頂元素不相等
34                     return tempNodeA;
35             }
36             else
37                 break;
38         }
39         return NULL;
40     }
41 };