7.剑指offer-链表中环的入口节点

来源:互联网 发布:淘宝冲印照片哪家好 编辑:程序博客网 时间:2024/04/28 02:52

1.题目

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

2.基本思路

设链表中有m个节点

方法1:

  • 遍历链表,将访问过的节点存储在一个表中,边访问边查询,如果访问的节点已经在表中出现,则为环的入口节点
  • 时间复杂度O(m) ,空间复杂度O(m)

方法2:

  • 首选计算环的长度,假设环的长度为n
    • 用快慢指针,慢指针一次走一步;快指针一次走两步, 则快指针速度比慢指针快一倍。无论在环中走多少次,快指针总能追上慢指针
  • 其次,一快一慢指针,快指针的开始位置比慢指针快n步,慢指针从表头开始。当两个指针相等的时候,则为环的入口

3.代码

  • 方法1

      ListNode* EntryNodeOfLoop(ListNode* pHead)  {    if(pHead==NULL)          return NULL;      set<ListNode*> s;      ListNode *p=pHead;      ListNode *res=NULL;      while(p!=NULL){ // 如果无环,尾指针肯定指向NULL          if(s.find(p)!=s.end()){              res=p;              break;          }else{              s.insert(p);          }          p=p->next;      }      return res;  }
  • 方法2

      int calCirclelength(ListNode *pHead){      int res=0;      if(pHead==NULL || pHead->next==NULL)          return res;      ListNode *pLow,*pHigh;      pLow=pHead;      pHigh=pHead->next;      while(pLow!=NULL && pHigh!=NULL && pLow!=pHigh){          pLow=pLow->next;          if(pHigh->next)              pHigh=pHigh->next->next;      }      if(pHigh->next==NULL){        return res;      }      pHigh=pLow->next;      ++res;      while(pHigh!=pLow){          ++res;          pHigh=pHigh->next;      }      return res;  }  ListNode* EntryNodeOfLoop(ListNode* pHead)  {    if(pHead==NULL)          return NULL;      int num=calCirclelength(pHead); // 如果num计算错误,则有可能陷入死循环之中,代码果然是多一行就多一个潜在bug的危险      if(num==0)          return NULL;      ListNode *p,*p1;      p=pHead;      int i=0;      while( i < num){          p=p->next;          ++i;      }      p1=pHead;      while(p1!=p){          p1=p1->next;          p=p->next;      }      return p;  }

0 0
原创粉丝点击