java - 一段遞歸代碼的問題
問題描述
在一篇博客上看到了一個遞歸函數(shù),但我感覺劃線的那一行似乎永遠不為true呢?
因為函數(shù)里的第一個判斷條件:
if (!root || p == root || q == root) return root;
就決定了left必定是p,q,null之一吧?
我對遞歸的理解不太深刻,不知道理解的對不對?謝謝。
問題解答
回答1:首先你要弄明白,這個遞歸函數(shù)的返回值有4種可能:
null,表示這次遞歸已經(jīng)碰到葉子節(jié)點,無法再繼續(xù)下去了。
p,表示這次遞歸已經(jīng)碰到p節(jié)點了。
q,表示這次遞歸已經(jīng)碰到q節(jié)點了。
lowestCommonAncestor,表示已經(jīng)找到的最低公共祖先節(jié)點。
為何這樣說,前3種可能,你應(yīng)該很好理解,因為從<1> if (!root || p == root || q == root) return root;這行代碼可以看出來。
那么再看(我就簡寫了)<2> left = lowestCommonAncestor(left, p, q);<3> right = lowestCommonAncestor(right, p, q);這兩行。在真正的lowestCommonAncestor被找到之前,這個函數(shù)只可能會返回null,q,p。再看這兩行判斷<4> if (left && left != p && left != q) return left;<5> if (right && right != p && right != q) return right;當(dāng)<2>,<3>兩處的返回值是null,p,q的時候,這兩處判斷的條件都無法滿足,所以不會返回。所以要進入再下面的判斷<6> if (left && right) return root;這句什么意思?如果從<4>,<5>的判斷處沒有返回,說明left和right只能是null,p,q中的一個,而這里了又限定了left和right必須是非null,意思就是這時候left和right必定一個是p,一個是q。那么這個時候,本層遞歸函數(shù)的root(注意是本層遞歸函數(shù))就是那個lowestCommonAncesstor,于是就返回它。最后一句<7> return left ? left : right;既然到了這里,就說明left和right里面至少有一個是null,那么就返回非null的那個,或者如果兩個都是null就返回null。
現(xiàn)在倒回去再看一下lowestCommonAncesstor這個遞歸函數(shù)在<2>,<3>兩處的調(diào)用,你可以把它看成是去當(dāng)前節(jié)點的left和right中分別去尋找p,和q,那么無非結(jié)果有4種:
返回null,說明p,q根本不在這個分支中。
返回p,說明這個分支中只有p,沒有q。
返回q,說明這個分支中只有q,沒有p。
返回lowestCommonAncesstor,說明這個分支中既有p又有q,于是就已經(jīng)找到他們的公共祖先啦!
可能說的還是不夠透徹,希望對你有幫助:)
回答2:第一個條件是判斷root,第二個是判斷l(xiāng)eft,有什么聯(lián)系嗎?
相關(guān)文章:
1. Docker for Mac 創(chuàng)建的dnsmasq容器連不上/不工作的問題2. html5 - 這個代碼顯示功能如何實現(xiàn)?3. java - 關(guān)于File的問題?4. java - instance method中 static后的<K>是什么意思?5. node.js - 終端 遠程連接服務(wù)器,終端關(guān)閉后,服務(wù)器無法運行6. 錯誤:java.lang.NoSuchMethodError:org.objectweb.asm.ClassWriter。<init>(I)V7. python3.x - python連oanda的模擬交易api獲取json問題第五問8. javascript - QWebEngineView 如何爬 angular 的動態(tài)數(shù)據(jù)?9. docker - 如何修改運行中容器的配置10. docker-machine添加一個已有的docker主機問題
