鏈表常見面試題三:解決鏈表帶環問題

問題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;
}

 

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