剑指offer_编程题_链表中环的入口结点

  • 题目
    给一个链表,若其中包含环,请找出该链表的环的入口结点,
    否则,输出null。
    
  1. 遍历链表并存储,若发现一节点已经遍历过,则该节点为入口结点
    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
            val(x), next(NULL) {
        }
    };
    */
    class Solution {
    public:
        ListNode* EntryNodeOfLoop(ListNode* pHead)
        {
     	   if (pHead==NULL)
     		   return NULL;
     	   ListNode* temp = pHead;
     	   std::map<ListNode*, int> m;
     	   while(temp->next!=NULL)
     	   {
     		   if (m.count(temp)>0)
     			   return temp;
     		   else
     			   m[temp] = 1;
     		   temp = temp->next;
     	   }
     	   return NULL;
        }
    };
    
  2. 遍历链表,并将已遍历节点的next指向一个自定义的节点
    若即将遍历的节点指向自定义的节点,则为入口结点
    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
            val(x), next(NULL) {
        }
    };
    */
    class Solution {
    public:
        ListNode* EntryNodeOfLoop(ListNode* pHead)
        {
     	   if (pHead==NULL)
     		   return NULL;
     	   ListNode* mybase = new ListNode(0);
     	   ListNode* temp;
     	   while(pHead->next!=NULL&&pHead->next!=mybase)
     	   {
     		   temp = pHead->next;
     		   pHead->next = mybase;
     		   pHead = temp;
     	   }
     	   if (pHead->next==NULL)
     		   return NULL;
     	   else 
     		   return pHead;
        }
    };
    
  3. 通过两个指针分别以1的速度、2的速度移动,若存在环,则两指针必定相遇
    假设存在环,环长为n,即节点数量为n,并设入口点为第一个节点
    当1走到环的第一个节点时,2可能出现在环上的任意一点x(1<=x<=n)
    ①此时,如果2降低速度为1,那么2永远处在1的前方(x-1)个位置
    如果2停下,1需要走(x-1)与2相遇
    也就是说,1如果从开始处出发,2在环的第一个节点处等待(x-1)个时间后以与1相同的速度出发,那么两指针会相遇
    ②当1走到环的第一个节点时,如果2仍然以2的速度前进,两者速度2比1快1,2将会追上1
    环长为n,2在1的前方(x-1)个位置,2如果要追上1,需要[n-(x-1)]个时间
    即1和2的相遇点为(1+[n-(x-1)]),相遇点到环的第一个节点的距离为(n-[(1+[n-(x-1)])-1])=(x-1)
    由①1如果从开始处出发,2在环的第一个节点处等待(x-1)个时间后以与1相同的速度出发,那么两指针会在入口处相遇
    所以有1从开始处出发,2从相遇点出发,以同样的速度1,两个指针在入口会相遇
    参考
    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
            val(x), next(NULL) {
        }
    };
    */
    class Solution {
    public:
        ListNode* EntryNodeOfLoop(ListNode* pHead)
        {
     	   if (pHead==NULL)
     		   return NULL;
     	   ListNode* p1=pHead;
     	   ListNode* p2=pHead;
     	   while(p2!=NULL&&p2->next!=NULL)
     	   {
     		   p1 = p1->next;
     		   p2 = p2->next->next;
     		   if (p1==p2)
     		   {
     			   p1 = pHead;
     			   while(p1!=p2)
     			   {
     				   p1 = p1->next;
     				   p2 = p2->next;
     			   }
     			   return p1;
     		   }
     	   }
     	   return NULL;
        }
    };
    
发布了80 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/C_abua/article/details/105749408