两个链表的第一个公共节点(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 };
posted @ 2020-07-17 10:36  孔子?孟子?小柱子!  阅读(213)  评论(0编辑  收藏  举报