若是一個節點的左右子樹上分別有兩個節點,那麼這棵樹是祖先,可是不必定是最小的,可是從下邊開始判斷,找到後一直返回到上邊就是最小的。spa
若是一個節點的左右子樹上只有一個子樹上遍歷到了節點,那麼那個子樹多是一個節點的祖先,也多是兩個節點的祖先,若是是一個節點的祖先,那麼公共祖先還在上邊,還須要返回結果進行判斷,若是是兩個節點的祖先,那麼最小公共祖先就是這個或者在下邊,總之,返回有結果的那個子樹就是了。code
因此思路就是,往下遍歷,直到找到節點而後返回,返回之後判斷此時左右子樹的狀況,根據狀況返回根節點的遞歸結果或者子樹的遞歸結果blog
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { /* 從底下開始判斷,兩個節點是否是在左右子樹上 */ if(root==null) return null; //若是遍歷到了某個節點,說明這個節點在這個子樹上,返回這個節點 if (root==p||root==q) return root; //若是還沒遍歷到,那麼公共節點確定在下邊,繼續往下尋找左子樹和右子樹 //返回的兩個分別是左、右子樹上遍歷到的某個節點的祖先 TreeNode lt = lowestCommonAncestor(root.left,p,q); TreeNode rt = lowestCommonAncestor(root.right,p,q); //若是左右子樹都找到了,那麼這個節點就是公共祖先 if (lt!=null&&rt!=null) return root; //若是有空缺,那麼返回那個找到的,這種狀況是到如今爲止,兩個節點已經在一棵子樹上了,返回以當前子樹爲起點的運算結果就行 return (lt==null)?rt:lt; }