單鏈表面試題集合

一、找出單鏈表的倒數第K個元素(僅容許遍歷一遍鏈表)

     使用指針追趕的方法。定義兩個指針fast和slow,fast先走K步,而後fast和slow同時繼續走。當fast到鏈表尾部時,slow指向倒數第K個。注意要考慮鏈表長度應該大於K。

二、找出單鏈表的中間元素(僅容許遍歷一遍鏈表)

     使用指針追趕的方法。fast每次走一步,slow每次走兩步。當fast到鏈表尾部時,slow指向鏈表的中間元素。


三、判斷單鏈表是否有環?

     方法一:使用指針追趕的方法。slow指針每次走一步,fast指針每次走兩步。如存在環,則二者相遇;如不存在環,fast遇到NULL退出。

     方法二:使用p、q兩個指針,p老是向前走,但q每次都從頭開始走。

四、如何知道環的長度?

     記錄下碰撞點(或者找在環中任意一結點均可以),讓slow從碰撞點開始,繞着環走一圈,再次到碰撞點的位置時,所走過的結點數就是環的長度s。

五、如何找到環的入口?
    
     分別從碰撞點、頭指針開始走,相遇的那個點就是鏈接點。

六、判斷兩個鏈表(無環)是否相交?

     方法一:採用暴力的方法,遍歷兩個鏈表,在遍歷的過程當中進行比較,看節點是否相同。

     方法二:兩鏈表一旦相交,相交節點必定有相同的內存地址,所以利用內存地址創建哈希表,如此經過判斷兩個鏈表中是否存在內存地址相同的節點判斷兩個鏈表是否相交。具體作法是:遍歷第一個鏈表,並利用地址創建哈希表,遍歷第二個鏈表,看看地址哈希值是否和第一個表中的節點地址值有相同便可判斷兩個鏈表是否相交。時間複雜度O((length(A)+ length(B))

     方法三:問題轉化法。先遍歷第一個鏈表到其尾部,而後將尾部的本來指向NULL的next指針指向第二個鏈表。這樣兩個鏈表就合成了一個鏈表,問題轉變爲判斷新的鏈表是否有環?

     方法四:一旦兩個鏈表相交,那麼兩個鏈表從相交節點開始到尾節點必定都是相同的節點。因此,若是他們相交的話,那麼他們最後的一個節點必定是相同的,所以分別遍歷到兩個鏈表的尾部,而後判斷他們是否相同。

七、如何知道兩個單鏈表(可能有環)是否相交

思路:根據兩個鏈表是否有環來分別處理,若相交這個環屬於兩個鏈表共有

(1)若是兩個鏈表都沒有環。

(2)一個有環,一個沒環。確定不相交

(3)兩個都有環。
     ①求出A的環入口,判斷其是否在B鏈表上,若是在,則相交。
     ② 在A鏈表上,使用指針追趕的方法,找到兩個指針碰撞點,以後判斷碰撞點是否在B鏈表上。若是在,則相交。

八、尋找兩個相交鏈表的第一個公共節點  

     方法一:最簡單的方法就是先順序訪問其中一個鏈表,在每訪問一個節點時,都對另一個鏈表進行遍歷,直到找到一個相等的節點位置,若是鏈表長度分別是m,n 則時間複雜度爲O(mn)。

     方法二:(兩種狀況)
            
     ① 相交的點,在環外。若是兩個鏈表有公共節點,那麼該公共節點以後的全部節點都是兩個鏈表所共有的,因此長度必定也是相等的,若是兩個鏈表的總長度是相等的,那麼咱們對兩個鏈表進行遍歷,則必定同時到達第一個公共節點。可是鏈表的長度實際上不必定相同,因此計算出兩個鏈表的長度之差n,而後讓長的那個鏈表先移動n步,短的鏈表再開始向後遍歷,這樣他們必定同時到達第一個公共節點,咱們只須要在向後移動的時候比較兩個鏈表的節點是否相等就能夠得到第一個公共節點。時間複雜度是O(m+n)。

           
     ② 相交的點在環內。當交點在環中時,此時的交點能夠是A鏈表中的環入口點,也能夠是B鏈表中環入口點。這是由於若是把B看出一個完整的鏈表,而A指向了B鏈表,則此時交點是A的環入口點。反之交點是鏈表B的環入口點。     
     思路:根據上述分析,能夠直接求出A的環入口點或者B的環入口點就能夠了。
相關文章
相關標籤/搜索