1. 程式人生 > >單鏈表面試題集合

單鏈表面試題集合

1、找出單鏈表的倒數第K個元素(僅允許遍歷一遍連結串列)      使用指標追趕的方法。定義兩個指標fast和slow,fast先走K步,然後fast和slow同時繼續走。當fast到連結串列尾部時,slow指向倒數第K個。注意要考慮連結串列長度應該大於K。 2、找出單鏈表的中間元素(僅允許遍歷一遍連結串列)      使用指標追趕的方法。fast每次走倆步,slow每次走一步。當fast到連結串列尾部時,slow指向連結串列的中間元素。 3、判斷單鏈表是否有環?      方法一:使用指標追趕的方法。slow指標每次走一步,fast指標每次走兩步。如存在環,則兩者相遇;如不存在環,fast遇到NULL退出。
     方法二:使用p、q兩個指標,p總是向前走,但q每次都從頭開始走。 4、如何知道環的長度?      記錄下碰撞點(或者找在環中任意一結點都可以),讓slow從碰撞點開始,繞著環走一圈,再次到碰撞點的位置時,所走過的結點數就是環的長度s。 5、如何找到環的入口?      分別從碰撞點、頭指標開始走,相遇的那個點就是連線點。 6、判斷兩個連結串列(無環)是否相交?      方法一:採用暴力的方法,遍歷兩個連結串列,在遍歷的過程中進行比較,看節點是否相同。      方法二:兩連結串列一旦相交,相交節點一定有相同的記憶體地址,因此利用記憶體地址建立雜湊表,如此通過判斷兩個連結串列中是否存在記憶體地址相同的節點判斷兩個連結串列是否相交。具體做法是:遍歷第一個連結串列,並利用地址建立雜湊表,遍歷第二個連結串列,看看地址雜湊值是否和第一個表中的節點地址值有相同即可判斷兩個連結串列是否相交。時間複雜度O((length(A)+ length(B))
     方法三:問題轉化法。先遍歷第一個連結串列到其尾部,然後將尾部的原本指向NULL的next指標指向第二個連結串列。這樣兩個連結串列就合成了一個連結串列,問題轉變為判斷新的連結串列是否有環?      方法四:一旦兩個連結串列相交,那麼兩個連結串列從相交節點開始到尾節點一定都是相同的節點。所以,如果他們相交的話,那麼他們最後的一個節點一定是相同的,因此分別遍歷到兩個連結串列的尾部,然後判斷他們是否相同。 7、如何知道兩個單鏈表(可能有環)是否相交 思路:根據兩個連結串列是否有環來分別處理,若相交這個環屬於兩個連結串列共有 (1)如果兩個連結串列都沒有環。 (2)一個有環,一個沒環。肯定不相交
(3)兩個都有環。      ①求出A的環入口,判斷其是否在B連結串列上,如果在,則相交。      ② 在A連結串列上,使用指標追趕的方法,找到兩個指標碰撞點,之後判斷碰撞點是否在B連結串列上。如果在,則相交。 8、尋找兩個相交連結串列的第一個公共節點        方法一:最簡單的方法就是先順序訪問其中一個連結串列,在每訪問一個節點時,都對另外一個連結串列進行遍歷,直到找到一個相等的節點位置,如果連結串列長度分別是m,n 則時間複雜度為O(mn)。      方法二:(兩種情況)                   ① 相交的點,在環外。如果兩個連結串列有公共節點,那麼該公共節點之後的所有節點都是兩個連結串列所共有的,所以長度一定也是相等的,如果兩個連結串列的總長度是相等的,那麼我們對兩個連結串列進行遍歷,則一定同時到達第一個公共節點。但是連結串列的長度實際上不一定相同,所以計算出兩個連結串列的長度之差n,然後讓長的那個連結串列先移動n步,短的連結串列再開始向後遍歷,這樣他們一定同時到達第一個公共節點,我們只需要在向後移動的時候比較兩個連結串列的節點是否相等就可以獲得第一個公共節點。時間複雜度是O(m+n)。                  ② 相交的點在環內。當交點在環中時,此時的交點可以是A連結串列中的環入口點,也可以是B連結串列中環入口點。這是因為如果把B看出一個完整的連結串列,而A指向了B連結串列,則此時交點是A的環入口點。反之交點是連結串列B的環入口點。           思路:根據上述分析,可以直接求出A的環入口點或者B的環入口點就可以了。