剑指offer---两个链表的第一个公共结点

问题:两个链表的第一个公共结点

要求:输入两个链表,找出它们的第一个公共结点。 

 1 struct ListNode {
 2     int val;
 3     struct ListNode *next;
 4     ListNode(int x) :
 5             val(x), next(NULL) {
 6     }
 7 };*
 8 class Solution {
 9 public:
10     ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
11 
12     }
13 };

 首先明确:

想到两个链表的交叉情况,我们第一意识就是图 2所示的情况。然而从单向链表的节点结构来看,如果两个链表有公共节点,那么这两个链表从某一个节点开始,他们的next都指向同一个节点,且之后所有的节点都会重合,如图1所示,才是两个单向链表交叉的情况,即Y型交叉。

解题方法:

方法一: 暴力法,挨个遍历,时间复杂度O(m*n);

方法二: 辅助栈,为两个链表建立两个辅助栈,将每个链表遍历到各自的辅助栈,栈顶元素就是链表尾节点,然后比较栈顶两个元素是否相同,若相同,弹出栈顶元素继续比较,知道找到最后一个相同的元素,时间复杂度和空间复杂度都为O(m+n);

方法三:先遍历两个链表得到各自长度,求得两个链表的长度差 lengthDif 。首先遍历较长链表  lengthDif  步,然后两个链表同时开始遍历,直到找到两个地址相同的元素。时间复杂度O(m+n),不需要辅助栈。

解题代码:

 1 struct ListNode {
 2     int val;
 3     struct ListNode *next;
 4     ListNode(int x) :
 5             val(x), next(NULL) {
 6     }
 7 };*
 8 class Solution {
 9 public:
10     ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
11         auto length1 = getSize(pHead1);
12         auto length2 = getSize(pHead2);
13         int lengthDif = length1 - length2;
14         ListNode *pLong = pHead1;
15         ListNode *pShort = pHead2;
16         if(length1 < length2){
17             pLong = pHead2;
18             pShort = pHead1;
19             lengthDif = length2 - length1;
20         }
21 
22         for(int i=0; i<lengthDif; i++)
23             pLong = pLong->next;
24 
25         while((pLong != nullptr) && (pShort != nullptr) && (pLong != pShort)){
26             pLong = pLong->next;
27             pShort =pShort->next;
28         }
29         ListNode *pCommonNode = pLong;
30         return pCommonNode;
31     }
32 
33     unsigned int getSize(ListNode *pHead){
34         unsigned int size = 0;
35         ListNode *p = pHead;
36         while(p != nullptr){
37             size++;
38             p = p->next;
39         }
40         return size;
41     }
42 };

 

posted on 2018-10-12 11:18  wangzhch  阅读(493)  评论(0编辑  收藏  举报

导航