上篇我們主要介紹鍊錶反轉的原地反轉解法。
除此以外,是否還有其他解法?
當然,今天就來看看鍊錶反轉的遞迴解法。
遞迴,字面意思,有」遞「也有」歸「
拿我們經常聽到的斐波那契數列來說,公式如下
f(n) = f(n-1) + f(n-2); f(1) = 1, f(2) = 1
現在比如求解f(5)的值,按照公式,可以展開為f(5) = f(4) + f(3),如下圖所示
這時候,我們不知道f(3)和f(4)的值,沒關係,繼續展開,如下圖所示
從圖中可以看出,各個節點已經分解到不能再分解,此時的葉子節點都是已知值,f(1)=1,f(2)=2
」遞「過程走完了,下面開始」歸「
如上圖所示,沿著紅色箭頭的方向開始回歸,最終得到f(5)的值為8
如上就是遞迴的過程,從下面的**層面,我們可以看到底層的表示形式就是自己呼叫自己,直到滿足閾值條件則停止。
先上**
func reverse(head *listnode) *listnode結合下圖newhead := reverse(head.next)
head.next.next = head
head.next = nil
return newhead
}
我們假設此時傳入的head指向的是帶反轉的鍊錶,目前head的值為5。
既然這裡用到了遞迴的思想,那麼這裡
newhead := reverse(head.next)
head.next即為4,我們拿到的newhead此時就是乙個已經完成反轉的鍊錶了,這是目前還差5這個節點。
下面只要將4指向5,再讓5的next指向nil,就是乙個完整的反轉鍊錶了。
head.next.next = head即表示4指向5(head.next為4,head為5)
head.next = nil(5的下乙個節點即head.next)
5和4的關係是這樣,以此類推,4和3,3和2,2和1都是這樣遞迴來的。
這裡是比較繞,大概明白這個思想吧。
老王:你不好好種地,你以後長大能幹什麼
小王:學演算法
老王:學演算法?!你陣列、鍊錶、棧、佇列、堆、排序、查詢都整不明白,你學什麼演算法
小王:我只學鍊錶反轉遞迴解法
老王:。。。
日拱一卒 鍊錶 判斷鍊錶是否有環
判定乙個鍊錶是否有環 這張圖不存在環,頭結點是1,尾結點是5。這張圖中,節點2 3 4 5 2就構成了環。思路1 快慢指標 顧名思義,乙個快指標,乙個慢指標。如果不包括環,快慢指標同向行駛,根據小學經典數學題,他們永遠無法相遇,而且差距只會越來越大。如果鍊錶有環,意味著快慢指標都會調頭,好比操場跑步...
日拱一卒 鍊錶 如何實現lru
redis的記憶體淘汰機制好幾種,如ttl random lru。lru less recently used 即最近最少使用策略,表示在最近一段時間內最少被使用到的redis鍵,如果遇到記憶體不足,會有限淘汰這部分鍵來騰出更多空間。今天就來說說lru這種淘汰策略是如何通過鍊錶這種結構實現的。在鍊錶...
鍊錶的反轉 遞迴實現
此處明確了實現的方法,另外非遞迴 迭代 的方法也可行。首先我們需要知道一些基礎知識 即遞迴的相關概念。遞迴 recursion 即函式自己呼叫自己,若問題可以使用遞迴來解決,則必須滿足以下三個條件 1.可以要把解決的乙個問題轉化為乙個新的問題,這個新問題的解決思路與原來相同,只是在有規律的變化 例如...