兩個連結串列的第一個公共節點(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 = None5 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 };