以前據說過google面試反轉鏈表的梗,也嘗試着本身實現了一次,算是比較簡單的問題。但在紙上手寫代碼的時候,思惟就很亂,多是隔的時間長忘記了,或者以前就跟本沒有理清思路,因此被虐的很慘。
這篇文章的目的就是梳理一下思路,加深印象。若是有更好的算法,留言求虐啊~java
這是一個普通的鏈表,由ABCD4個節點組成,每一個節點都包含數據區-data和指向下一個節點的引用-nextnode
反轉鏈表,顧名思義就是將鏈表每一個節點的next引用反過來,如ABCD,變爲DCBA。固然,前提是咱們只持有頭節點的引用,且稱爲Node a,那麼鏈表反轉後的頭節點,就是Node d。面試
要將此鏈表反轉,咱們核心的需求是:修改每個節點的next引用,將next指向前一個節點,將原來的頭節點A中的next,指向null。算法
既然每個節點都須要操做,那就考慮循環吧,設一個索引(或者稱爲遊標)node(能夠利用節點A的引用),從節點A跑到節點D,當它再日後移動指向null時,循環結束。那麼循環邊界條件則爲google
while(node != null){ //do something }
而後咱們再看看每一個節點作一次反轉(即每次循環),都須要作什麼事情spa
在修改當前節點的next引用以前,要先保存其值,爲了不丟失下一個節點(即Node next
)的引用。3d
進行反轉,修改當前節點的next,使之指向上一個節點(即Node last
)code
要保存當前節點的引用,爲了提供給下一次循環時,對下個節點進行反轉blog
爲了保證while循環能夠從頭節點A遍歷到尾節點D,那麼遊標node在循環體最後要向後移動一個節點,即指向下一個節點。索引
Node reversalLinkedList(Node node){ Node last = null; Node next = null; while(node != null){ next = node.getNext();//1 拿到下個節點的引用,爲了提供給第4步使node向鏈表後方移動 node.setNext(last);//2 將當前節點指向上一個節點 last = node;//3 將last指向當前節點,提供給下次循環的第2步 node = next;//4 將當前節點的引用(即遊標)指向下一個節點 } /* * 循環完成後,node和next都指向了原節點D的next指向的位置,即null * 而last指向了上述null前面的位置,即節點D * 將last返回,則獲得鏈表ABCD反轉後鏈表DCBA的頭節點D */ return last; }
邏輯其實很簡單,須要注意的就是每次循環時須要暫存的引用 -- next,last
每次循環其實就是修改當前節點next的引用+三個引用(last,node,next)的後移,以下圖
第一次循環前
第一次循環的過程
第一次循環結束後
最後所有反轉後
保存當前節點,上一個節點,下一個節點的引用
每次循環最後,當前節點向後移動