C ++中的链接列表循环II

考虑我们有一个链表,我们必须检查是否有任何循环。为了表示给定链表中的循环,我们将使用一个称为pos的整数指针。该pos表示链表中连接了tail的位置。因此,如果pos为-1,则链表中没有循环。例如,链表类似于[5、3、2、0,-4、7],而pos =1。所以有一个循环,尾部连接到第二个节点。约束是我们不能修改列表

为了解决这个问题,我们将遵循以下步骤-

  • 慢:=头,快:=头

  • 虽然可以使用慢速,快速和快速度

    • 慢:=慢的下一个

    • 快速:=下一个(快速下一个)

    • 如果慢=快速,则中断

  • 如果fast不为空或first的下一个不为空,则返回null

  • 如果慢=快速,则

    • 慢:=慢和快的下一个:=快的下一个

    • 慢:=头

    • 慢不等于快

  • 返回慢

让我们看下面的实现以更好地理解-

示例

#include <bits/stdc++.h>
using namespace std;
class ListNode{
   public:
      int val;
      ListNode *next;
      ListNode(int data){
         val = data;
         next = NULL;
      }
};
ListNode *make_list(vector<int> v){
   ListNode *head = new ListNode(v[0]);
   for(int i = 1; i<v.size(); i++){
      ListNode *ptr = head;
      while(ptr->next != NULL){
         ptr = ptr->next;
      }
      ptr->next = new ListNode(v[i]);
   }
   return head;
}
ListNode *get_node(ListNode *head, int pos){
   ListNode *ptr = head;
   if(pos != -1){
      int p = 0;
      while(p < pos){
         ptr = ptr->next;
            p++;
      }
      return ptr;
   }
   return NULL;
}
class Solution {
   public:
   ListNode *detectCycle(ListNode *head) {
      ListNode* slow = head;
      ListNode* fast = head;
      while(slow && fast && fast->next){
         slow = slow->next;
         fast = fast->next->next;
         if(slow == fast)break;
      }
      if(!fast || !fast->next)return NULL;
      if(slow == fast){
         slow = head;
         while(slow!=fast){
            slow = slow->next;
            fast = fast->next;
         }
      }
      return slow;
   }
};
main(){
   Solution ob;
   vector<int> v = {5,3,2,0,-4,7};
   ListNode *head = make_list(v);
   int pos = 1;
   ListNode *lastNode = get_node(head, v.size() - 1);
   lastNode->next = get_node(head, pos);
   cout << "尾部连接到节点,其值:" <<ob.detectCycle(head)->val;
}

输入值

[5,3,2,0,-4,7]
1

输出结果

尾部连接到节点,其值:3