两个链表的第一个公共节点(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 };