55、剑指offer--链表中环的入口结点

题目描述

一个链表中包含环,请找出该链表的环的入口结点。

解题思路:先通过快慢指针,找到环中结点,以确定环中结点个数,然后两个指针,一个先走环中结点个数步,然后两个指针一起走,直到相遇得为入口节点

 1 /*
 2 struct ListNode {
 3     int val;
 4     struct ListNode *next;
 5     ListNode(int x) :
 6         val(x), next(NULL) {
 7     }
 8 };
 9 */
10 class Solution {
11 public:
12     //通过快慢指针找到在环中的相遇点
13     ListNode* MeetingNode(ListNode *pHead)
14     {
15         //找到在环中的结点--快慢指针
16         if(pHead == NULL)
17             return NULL;
18         ListNode *slow = pHead;
19         ListNode *fast = pHead;
20         while(fast != NULL && fast->next != NULL)
21         {
22             slow = slow->next;
23             fast = fast->next->next;
24             if(fast == slow)//注意此处先移动,再判断
25                 return fast;
26         }
27         return NULL;
28     }
29     ListNode* EntryNodeOfLoop(ListNode* pHead)
30     {
31         ListNode *meetNode = MeetingNode(pHead);
32         if(meetNode == NULL)
33             return NULL;
34         int nodesInLoop = 1;
35         ListNode *pNode1 = meetNode;
36         while(pNode1->next != meetNode)
37         {
38             pNode1 = pNode1->next;
39             nodesInLoop++;
40         }
41         pNode1 = pHead;
42         for(int i=0;i<nodesInLoop;i++)
43         {
44             pNode1 = pNode1->next;
45         }
46         ListNode *pNode2 = pHead;
47         while(pNode1 != pNode2)
48         {
49             pNode1 = pNode1->next;
50             pNode2 = pNode2->next;
51         }
52         return pNode1;
53     }
54 };
时间: 2024-10-04 01:34:15

55、剑指offer--链表中环的入口结点的相关文章

剑指Offer-55.链表中环的入口结点(C++/Java)

题目: 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 分析: 利用快慢指针,如果链表中存在环的话,则快指针一定在环中的某个节点与慢指针相遇. 设头节点到链表的环的入口结点的结点个数为p,入口结点到两指针相遇结点的结点个数为a,相遇结点到入口结点的结点个数为b. 快指针每次走两个结点,慢指针每次走一个结点,到两指针相遇之时,访问的结点个数是两倍的关系,那么根据上面的条件我们知道. 2*(p+a) = p + a + b + a => p = b 也就是头结点到入口结点

剑指Offer55:链表中环的入口结点(Java)

参考"yu-wang"的博客:https://blog.csdn.net/ShanXi_wangyu/article/details/100542137 参考"Tom Hardy"的博客:https://blog.csdn.net/qq_29462849/article/details/90400558 思路分析: 网上有两种解法:一种是利用HashSet不包含重复元素性质:另一种利用两个前进速度不同的变量有环必会相遇. 方法一 利用hashset不存储重复的值性质

剑指offer---链表中环的入口结点

class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { vector<ListNode*> vec; ListNode* list = NULL; if (pHead == NULL) return NULL; int flag = 0; while (pHead != NULL) { vec.push_back(pHead); pHead = (pHead->next); for (int i = 0;

剑指offer 55. 链表中环的入口结点

55. 链表中环的入口结点 题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null 法一:(我没看懂) 思路:https://blog.nowcoder.net/n/76e8af2d2fad49f990cde6e6b60a4d79?f=comment 快慢指针,快指针一次走两步,慢指针一次走一步,相遇后,快指针回到头结点,以一次一步的速度和慢指针一起走,再次相遇的结点即是环的入口点 1 public class Solution { 2 3 public ListNo

链表中环的入口结点-剑指Offer

链表中环的入口结点 题目描述 一个链表中包含环,请找出该链表的环的入口结点. 思路 若该链表存在环,设置两个指针pSlow和pFast,pSlow每次走一步,pFast每次走两步,当pFast追上pSlow的时候,pFast比pSlow多走的正好是pSlow走的也就是环所包含的节点的个数. 所以,第二次走,一个从头结点开始,另一个从相遇节点开始,最终会在环的入口节点相遇 代码 /* public class ListNode { int val; ListNode next = null; Li

剑指offer链表题的双指针法总结

本篇博客旨在总结双指针法在剑指offer链表题中的应用 包括删除链表中重复的节点.链表中倒数第k个节点.链表中环的入口节点.反转链表.合并两个排序的链表.两个链表的第一个公共节点. 根据双指针的类型,可以大致分为三种: 第一种是间隔一定距离的双指针法,包括删除链表中重复的节点.链表中倒数第k个节点两题 删除链表中重复的节点 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5

剑指offer——链表相关问题总结

首先统一链表的数据结构为: struct ListNode { int val; struct ListNode *next; ListNode(int x) :val(x), next(NULL) {} }; 题目一:从尾到头打印链表:输入一个链表.从尾到头打印链表每一个节点的值. 分析: 难点在于链表仅仅有指向后继的指针,没有指向前驱的指针. 转换思路.结合栈后进先出的特点,能够遍历链表,依次将数据元素存入栈中,然后再依次出栈,即为从尾到头的顺序. vector<int> printLis

【剑指offer】q50:树中结点的最近祖先

#@ root: the root of searched tree #@ nodeToFind: the tree-node to be found #@ path: the path from root to node #@@ #@@ search tree referenced by root, and return the path #@@ from root to node, if node not exist, path = [] #@@ def getPath(root, node

整理剑指offer&mdash;链表操作

在链表中找到第一个含有某值的节点并删除该节点. 在这里我创建的链表里,头节点是不包含有效数据的,它只是起一个辅助作用,真正的链表数据从首节点开始. typedef struct Node{    int data; //数据域    struct Node * pNext; //指针域}NODE, *PNODE; 1: void RemoveNode(PNODE pHead, int val) 2: { 3: if(pHead == NULL || pHead->pNext == NULL) 4