|
| 1 | +# 《剑指offer》刷题笔记(链表):链表中环的入口结点 |
| 2 | + |
| 3 | +---------- |
| 4 | + |
| 5 | +- **转载请注明作者和出处:http://blog.csdn.net/u011475210** |
| 6 | +- **代码地址:https://github.com/WordZzzz/Note/tree/master/AtOffer** |
| 7 | +- **刷题平台:https://www.nowcoder.com/** |
| 8 | +- **题  库:剑指offer** |
| 9 | +- **编  者:WordZzzz** |
| 10 | + |
| 11 | +---------- |
| 12 | + |
| 13 | +[toc] |
| 14 | + |
| 15 | +## 题目描述 |
| 16 | + |
| 17 | +一个链表中包含环,请找出该链表的环的入口结点。 |
| 18 | + |
| 19 | +## 解题思路 |
| 20 | + |
| 21 | +我们可以用两个指针来解决此类问题。如果链表中的环有n个结点,指针P1先在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向环的入口结点时,第一个指针已经环绕着环走了一圈又回到了入口结点。如下图所示: |
| 22 | + |
| 23 | +<p></p> |
| 24 | +<div align=center><img src="http://img.blog.csdn.net/20171221160256337?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTQ3NTIxMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast"/></div> |
| 25 | +<p></p> |
| 26 | + |
| 27 | +那我们接下来要考虑的就是如何获取这个环的结点个数n了。我们可以用快慢指针来实现,如果两个指针相遇,表明链表存在环。两个指针相遇的结点一定是在环中。可以从这个结点出发,一边继续向前移动一边计数,当再次回到这个结点时,就可以得到环中结点数了。 |
| 28 | + |
| 29 | +## C++版代码实现 |
| 30 | + |
| 31 | +```c |
| 32 | +/* |
| 33 | +struct ListNode { |
| 34 | + int val; |
| 35 | + struct ListNode *next; |
| 36 | + ListNode(int x) : |
| 37 | + val(x), next(NULL) { |
| 38 | + } |
| 39 | +}; |
| 40 | +*/ |
| 41 | +class Solution { |
| 42 | +public: |
| 43 | + ListNode* MeetingNode(ListNode* pHead){ |
| 44 | + if(pHead == NULL) |
| 45 | + return NULL; |
| 46 | + |
| 47 | + ListNode* pSlow = pHead->next; |
| 48 | + if(pSlow == NULL) |
| 49 | + return NULL; |
| 50 | + |
| 51 | + ListNode* pFast = pSlow->next; |
| 52 | + while(pFast != NULL && pSlow != NULL){ |
| 53 | + if(pFast == pSlow) |
| 54 | + return pFast; |
| 55 | + |
| 56 | + pSlow = pSlow->next; |
| 57 | + |
| 58 | + pFast = pFast->next; |
| 59 | + if(pFast->next != NULL) |
| 60 | + pFast = pFast->next; |
| 61 | + } |
| 62 | + return NULL; |
| 63 | + } |
| 64 | + ListNode* EntryNodeOfLoop(ListNode* pHead) |
| 65 | + { |
| 66 | + ListNode* meetingNode = MeetingNode(pHead); |
| 67 | + if(meetingNode == NULL) |
| 68 | + return NULL; |
| 69 | + |
| 70 | + // 得到环中结点的数目 |
| 71 | + int nodesInLoop = 1; |
| 72 | + ListNode* pNode1 = meetingNode; |
| 73 | + while(pNode1->next != meetingNode){ |
| 74 | + pNode1 = pNode1->next; |
| 75 | + ++nodesInLoop; |
| 76 | + } |
| 77 | + |
| 78 | + // 先移动pNode1,次数为环中结点的数目 |
| 79 | + pNode1 = pHead; |
| 80 | + for(int i=0; i < nodesInLoop; ++i) |
| 81 | + pNode1 = pNode1->next; |
| 82 | + |
| 83 | + // 再移动pNode1和pNode2 |
| 84 | + ListNode* pNode2 = pHead; |
| 85 | + while(pNode1 != pNode2){ |
| 86 | + pNode1 = pNode1->next; |
| 87 | + pNode2 = pNode2->next; |
| 88 | + } |
| 89 | + return pNode1; |
| 90 | + } |
| 91 | +}; |
| 92 | +``` |
| 93 | + |
| 94 | +**<font color="red" size=3 face="仿宋">系列教程持续发布中,欢迎订阅、关注、收藏、评论、点赞哦~~( ̄▽ ̄~)~</font>** |
| 95 | + |
| 96 | +**<font color="red" size=3 face="仿宋">完的汪(∪。∪)。。。zzz</font>** |
0 commit comments