链表常见面试题三:解决链表带环问题

问题1:判断链表是否带环

解题思路:

用两个指针,快指针一次走两步,慢指针一次走一步,如果两指针相遇,那么链表带环,若两指针不相遇,则链表不带环。

pLinkNode CheckCycle(pList head)
{
 pLinkNode fast = head;
 pLinkNode slow = head;
 while (fast && fast->next)
 {
  fast = fast->next->next;
  slow = slow->next;
  if (fast == slow)
  {
   return slow;   两指针相遇,链表带环,返回相遇点
  }
 }
 return NULL; //若两指针不相遇,返回null,链表不带环
}

问题2:若链表带环则求环的长度

解题思路:

面试题1已经判断过链表带环,且返回两指针相遇节点,求环长度时我们可以让一个指针从相遇节点处开始遍历,当再次回到相遇节点时,它走过的步数就是环的长度。

int GetCircleLength(pLinkNode meet)
{
 pLinkNode cur = meet;
 int count = 0;
 do
 {
  cur = cur->next; 
  count++;
 } while (cur != meet);
 return count;
}

问题3:获取环入口点

解题思路:

wKioL1agitHBrOW8AAAqqWXWZlE766.png

方法一:假设上图是一个单链表,两指针走到相遇节点时,慢指针走了x+y步,快指针走了x+y+nl步,(l为环的长度),由于快指针速度是慢指针速度的一倍,那么就有以下的等式:
(x+y)*2=x+y+nl;

化解可得:

x=nl-y;

那解题时我们可以用两个指针,一个指针从链表的开始位置走,另一个指针从相遇的节点处开始走,也就是y,两个指针相遇的节点就是入口点。

pLinkNode GetCycleEntryNode(pList head, pLinkNode MeetNode)
{
 pLinkNode Entry= head;
 pLinkNode meet = MeetNode;
 while (meet != Entry)
 {
  Entry = Entry->next;
  meet = meet->next;
 }
 return Entry;
}

方法二:

wKioL1agj_zjRiIgAAAu_c4lJeI063.png

将相遇的节点处断开,转化为两条链表相交求交点问题,两个指针meet和Entry分别遍历到链表尾,记录两链表的长度len_l1和len_l2,然后让较长的链表先走len=|len_l1 - len_l2|步,然后两指针一起走,直到两指针相遇,相遇的节点就是链表的交点,即环的入口点。

pLinkNode _GetCycleEntryNode(pList head, pLinkNode MeetNode)//链表带环转化为链表相交问题获取入口

{
 pLinkNode Entry = head;
 pLinkNode meet = MeetNode->next;
 int len_head = 0;
 int len_meet = 0;
 int len = 0;
 while (Entry != MeetNode) //求链表长度
 {
  len_head++;
  Entry = Entry->next;
 }
 while (meet != MeetNode)//求链表长度
 {
  len_meet++;
  meet = meet->next;
 }
  Entry = head;
  meet = MeetNode->next;
 if (len_head > len_meet)  
 {
  len = len_head - len_meet;
  while (len--)
  {
   Entry = Entry->next;
  }//较长链表先走len=|len_l1 - len_l2|步
 }
 else
 {
  len = len_meet - len_head;
  while (len--)
  {
   meet = meet->next;
  }//较长链表先走len=|len_l1 - len_l2|步
 }
 while (meet != Entry)
 {
  Entry = Entry->next;
  meet = meet->next;
 } //两指针同时走,相遇节点就是环入口点
 return Entry;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章