假設a的推薦人是b,b的推薦人是c,如何來查詢a的最終推薦人呢?
這裡直接給出答案——
long
findrootrerfererid
(long actorid)
遞迴是一種應用非常廣泛的演算法,亦可稱作程式設計技巧。
遞迴顧名思義,包含遞與歸兩個過程。我們用下面的例子來體會一下。
假設你去電影院看電影,你想知道自己坐在第幾排,所以你詢問前排的人,但前排的人有相同的困惑,他又去問他的前排,直到第一排的人明確自己坐在第幾排。然後每一排的人將結果告訴自己的後排,整個遞迴的過程就完成了。
這個小例子中,第一排是終止條件,不斷問前排的人是遞迴條件。無疑是很典型的遞迴問題,但面對遞迴問題更通常的反應是看了全會,寫了全廢。所以我們還要按部就班的學習遞迴的知識。。。
乙個問題的解可以分解為幾個子問題的解
設個問題與分解後的問題除了問題規模不同外,求解思路完全相同
存在遞迴終止條件
編寫遞迴**的核心無非就兩個:遞迴公式+終止條件。我們通過下面的小例子來理解下——
假設有n個台階,每次你自己可以跨越1個台階或者2個台階。請問走這n個台階共有多少種走法?
我們會想到,可以按照第一步的走法將問題分解為兩個子問題,也就是走一步之後的走法和走兩步之後的走法,對應的遞迴公式就是
f (n
)=f(
n−1)
+f(n
−2
)f(n) = f(n-1)+f(n-2)
f(n)=f
(n−1
)+f(
n−2)
再來確定終止條件,顯然,當只有乙個台階時就沒必要再遞迴了,也就是:
f (1
)=
1f(1)=1
f(1)=1
將這個遞迴終止條件帶入遞迴公式後,發現f(2)是無法確定的,所以終止條件還應該包含
f (2
)=
2f(2)=2
f(2)=2
表示的含義是走兩個台階有兩種走法。最後我們將其轉換為**實現——
intf(
int n)
站在巨人的肩膀——
寫遞迴**的關鍵在於找到將大問題轉化為小問題的關鍵,並且基於此寫下遞迴公式,然後再推敲遞迴終止條件,最終將遞迴公式和遞迴條件轉化為**實現。遞迴**在簡潔可讀性強的同時,卻也帶來了堆疊溢位的隱患。
之前提到過系統沒呼叫乙個函式,會將臨時變數作為棧幀壓棧,等到函式返回再彈棧。而遞迴**因為呼叫的函式層數多,在函式呼叫時不斷申請棧空間。從而導致空間複雜度不理想。
那怎樣避免呢?理想的方法是根據場景選擇遞迴,如果遞迴層數不多,則限制遞迴層數,這時使用遞迴是合適的。
在剛才走台階的例子中,就不可避免的遇到了重複計算的問題,這樣對問題的求解並沒有障礙,但並不優雅,我們要使用哈比表這樣的資料結構動態儲存每個子問題的結果。
在問題規模較大時,有什麼比較好的除錯方式——
日拱一卒,功不唐捐。
《資料結構與演算法之美》07 遞迴
一 如何理解 遞迴 遞迴是一種應用非常廣泛的演算法 或者程式設計技巧 二 遞迴的三個條件 1 乙個問題的解可以分解為幾個子問題的解 2 這個問題與分解之後的子問題,除了資料規模不同,求解思路完全一樣 3 存在遞迴終止條件 三 如何編寫遞迴 寫遞迴 最關鍵的是 找到如何將大問題分解為小問題的規律,並且...
資料結構與演算法之美 8 遞迴演算法
遞迴嚴格說起來不算一種演算法,只能說是一種問題處理思想或者問題處理技巧。只要問題同時滿足以下三個條件,就可以考慮用遞迴來解決 乙個問題的解可以分解為幾個子問題的解 這個問題與分解之後的子問題,除了資料規模不同,求解思路完全一樣 存在遞迴終止條件 個人覺得,寫遞迴 最關鍵的是寫出遞推公式,找到終止條件...
資料結構與演算法之美
什麼是資料結構?什麼是演算法 狹義重點 複雜度分析 方法 邊學邊練,適度刷題 複雜度分析 時間複雜度 常見時間複雜度 非多項式量級 非常低效的演算法 空間複雜度 漸進空間複雜度,表示演算法的儲存空間和資料規模的增長關係 最好情況時間複雜度 理想情況的時間複雜度 最壞情況時間複雜度 最糟糕的情況下的時...