題源
牛客網——直通bat面試演算法精講課 題目
給定乙個單鏈表的頭結點head,判斷其是否有環,
無環返回-1; 有環返回 入環 的 第乙個 結點的 數值。
要求:如果鍊錶長度是n個節點,請做到 時間複雜度為o(n),額外空間複雜度為o(1)。
演算法思想的說明
1.單鏈表 每個結點只有 乙個next域(或者稱為指標域/鏈域)
2.乙個有環單鏈表 形如:
為了找到 入環的第乙個結點,可以設定2個結點slow和quick。
slow和quick的初始都賦值為head,之後slow以1為步長向後遍歷,而quick以2為步長向後遍歷,
即:slow = slow->next;quick = quick->next->next。
因為quick步長大於slow,走得比slow快,且quick步長為2,
所以 如果 乙個單鏈表沒有環,那麼quick最先 要麼 本身是null,要麼quick->next是null。
如果有環,以上圖2個有環單鏈表為例子,看如何可以找到 入環的 第乙個結點:
上圖單鏈表1:
初始:(quick = head) == (slow = head)
接著quick以2為步長,slow以1為步長遍歷鍊錶
:——>quick = 2, slow = 1
——>quick = 4, slow = 2
——>
quick = 2, slow = 3
——>(
quick = 4) == (slow = 4)
至此,quick與slow首次相遇,
接著,令quick再更新為head,slow不變,一起以1為步長 遍歷鍊錶,
待slow與quick第二次相遇,它們所在的那個結點 就是 入環的 第乙個結點。
即:quick = head, slow = 4
——>(quick = 1) == (slow= 1),1即入環的第乙個結點。
上圖單鏈表2:
初始:(quick = head) == (slow = head)
接著quick以2為步長,slow以1為步長遍歷鍊錶
:——>quick = 2, slow = 1
——>quick = 4, slow = 2
——>quick = 3, slow = 3
至此,quick與slow首次相遇,
接著,令quick再更新為head,slow不變,一起以1為步長 遍歷鍊錶,
待slow與quick第二次相遇,它們所在的那個結點 就是 入環的 第乙個結點。
即:quick = head, slow = 3
——>quick = 1, slow = 4
——>(quick = 2) == (slow= 2),2即入環的第乙個結點。 **
#include using namespace std;
struct node
};class chkloop
;int chkloop:: check_loop(node *head)
while(quick != slow);
quick = head;
while(quick!=slow)
return quick->val;
}//list 2,建立上面**所示的第2個有環鏈表
單鏈表判環判交問題
摘要 有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?擴充套件 判斷兩個單鏈表是否相交,如果相交,給出相交的第乙個點。有乙個單鏈表,其中可能有乙個環,也就是某...
單鏈表判環的討論
聊天時聽到的這個問題,即有乙個單鏈表,可能有環 見圖 請判斷出是否存在這個環?貌似這是很常見的面試題 我居然沒印象 既然有個環,那就直接遍歷一遍環唄,用個陣列標記一下。時間複雜度和空間複雜度都是o n 這個思路的問題就是在於空間複雜度是o n 所以面試中,面試官總會再問,有沒有更好的解決方法。然後我...
單鏈表判環判相交綜合題
給定兩個單鏈表的頭節點head1和head2,單鏈表可能有環,也可能無環。如何判斷兩個鍊錶是否相交?相交的話返回相交的第乙個節點,不想交的話返回null。要求 如果鍊錶1的長度為n,鍊錶2的長度為m,時間複雜度o n m 額外空間複雜度o 1 首先我們先判定兩個鍊錶是否有環,如果只有其中乙個鍊錶有環...