首页 > 其他 > 详细

指offer系列29:两个链表的第一个公共结点

时间:2019-07-13 15:34:41      阅读:114      评论:0      收藏:0      [点我收藏+]

       这个题我拿到的第一个想法确实是遍历两个链表,先遍历第一个链表,在遍历内部再遍历第二个链表。这样两个for循环就可以计算出一样的结点了。剑指offer这一章讲的是算法的效率问题,所以我想这个题一定有更快捷的方法。但是我想不出什么快速的办法,o(╥﹏╥)o看了剑指offer上的解法,主要其实就一句话。两个存在共同结点的链表在共同结点后的结点全是共同结点,因为我们计算的链表是单链表。所以这两个链表的拓扑形状应该是Y型,而不是X型。开始我自己想的时候就是想成了X型,因此想了半天没想到什么方案。有了这个思路之后,想到更快捷的方法就是顺其自然的事情了。

       剑指offer上提供了两种做法,首先是从后往前输出,因为链表的后半部分是一样的,但是前面却长短不一。这个剑指offer上的图画的很清楚。可是链表是一个从前向后的结构,没法从后向前输出,这个数据的特点“先进后出”,于是想到了栈。用栈做辅助结构,将链表的数据放进去,然后两个栈同时弹出相同数据,一直到找到最后一个相同的结点。这个思路听起来不错,但是最后剑指offer没有用它,我说一下原因。首先它需要两个辅助的栈的结构,增加了空间的开销来换时间的减少。实在不能说是上策。其次这个思路等于把链表里的数据放进栈里去操作,而这个题目最后返回的是链表的结点,也就是说在栈中找到了第一个相同的结点之后还要再去链表里找到,所以并不简便。

      第二种做法是先求出两个链表的长度,然后根据长度把更长的链表截成和短的一样长,然后从两个链表连个指针一起走,直到遇见相同的结点。这个结点无论是思路还是做法都很新颖简便,所以答案也采用了这种方法。

 1 #include<iostream>
 2 using namespace std;
 3 
 4 struct ListNode {
 5 int val;
 6 struct ListNode *next;
 7 /*
 8 ListNode(int x) :
 9 val(x), next(NULL) {
10 }
11 */
12 };
13 class Solution {
14 public:
15     ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
16         int len1 = getlen(pHead1);
17         int len2 = getlen(pHead2);
18         int gap=0;
19 
20         //这段不能写成if,else。因为if-else中是程序的一个小子块,这样内部定义的变量外面不能用
21         ListNode* plong = pHead1;//默认第一个长
22         ListNode* pshort = pHead2;
23         gap = len1 - len2;
24         if(len2>len1)//如果第二个长,修改值
25         {
26             ListNode* plong = pHead2;
27             ListNode* pshort = pHead1;
28             gap = len2 - len1;
29         }
30         for (int i = 0; i < gap; i++)//将两个链表拉到一样长
31         {
32             plong = plong->next;
33         }
34         while (plong != NULL&&pshort != NULL&&plong != pshort)//寻找一样的结点
35         {
36             plong = plong->next;
37             pshort = pshort->next;
38         }
39         ListNode* commonnode = plong;
40         return commonnode;
41     }
42     int getlen(ListNode* ln)
43     {
44         if (ln == NULL)
45             return 0;
46         int count = 0;
47         while (ln)
48         {
49             count++;
50             ln = ln->next;
51         }
52         return count;
53     }
54 };
55 int main()
56 {
57     Solution so;
58     ListNode common[2];
59     common[0].val = 6;
60     common[0].next = &common[1];
61     common[1].val = 7;
62     common[1].next = NULL;
63 
64     ListNode left[3];
65     left[0].val = 1;
66     left[0].next = &left[1];
67     left[1].val = 2;
68     left[1].next = &left[2];
69     left[2].val = 3;
70     left[2].next = &common[0];
71 
72     ListNode right[2];
73     right[0].val = 4;
74     right[0].next = &right[1];
75     right[1].val = 5;
76     right[1].next = &common[0];
77     
78     Solution solu;
79     ListNode *node = solu.FindFirstCommonNode(left, right);
80     while (node != NULL)
81     {
82         cout << node->val << " ";
83         node = node->next;
84     }
85     cout << endl;
86 
87     return 0;
88 }

指offer系列29:两个链表的第一个公共结点

原文:https://www.cnblogs.com/neverland0718/p/11180753.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!