劍指Offer 68 II 二叉樹的最近公共祖先

2022-03-06 11:05:25 字數 1926 閱讀 5486

劍指offer

contents思路2:到p,q的路徑的最後共同節點

解答解答2:到p,q的路徑的最後共同節點

輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1

輸出: 3

解釋: 節點 5 和節點 1 的最近公共祖先是節點 3。

示例 2:

輸入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4

輸出: 5

解釋: 節點 5 和節點 4 的最近公共祖先是節點 5。因為根據定義最近公共祖先節點可以為節點本身。

說明:所有節點的值都是唯一的。

p、q 為不同節點且均存在於給定的二叉樹中。

最近公共祖先只有三種情況:

p 和 q在 root的子樹中,且分列 root 的 異側(即分別在左、右子樹中);

p = root,且 q 在 root的左或右子樹中;

q = root ,且 p在 root 的左或右子樹中;

排除了上述情況之後,只剩下一種情況,即p 和 q在 root的子樹中,且都在 root 的 同側(即都在左子樹種或都在右子樹中),此時root必然不是最近的祖先,因為root下方肯定還有更近的祖先。

為什麼是後續遍歷?因為乙個節點是否是p,q的公共祖先,必須先看其左右子樹當中是否包含p,q。

終止條件

root == null || root == p || root == q,直接返回root。

遞推過程

開啟左子樹遞迴,也就是在左子樹繼續尋找p,q,並記錄返回值left

開啟右子樹遞迴,也就是在右子樹繼續尋找p,q,並記錄返回值right

返回值返回值表示的是最近公共祖先,沒找到最近公共祖先時,返回值都是null;找到了最近公共祖先後,會將這個節點回溯到二叉樹根節點,作為最後的返回值。

left和right都為空,說明當前節點的左右子樹裡找不到p,q的公共祖先,那麼返回null

left和right都不為空,說明p,q就分別在當前節點的左右子樹當中,當前節點就是公共祖先

left和right有乙個為空,另乙個非空,說明p,q只可能在非空的那個子樹當中,返回非空的子樹根節點

這是書上的解法,首先找到以根節點開始,以p,q結尾的兩條路徑。然後找到兩條路徑公共部分的最後乙個節點,就是最近的公共祖先節點。如下圖。

尋找路徑採用前序遍歷+回溯的方法。

class

solution

}

複雜度分析

時間複雜度o(n),最多需要遍歷所有節點

空間複雜度o(n),最差的時候,需要開啟n層遞迴,占用的棧空間是o(n)

class

solution

return res;

}//前序遍歷搜尋p,q,儲存路徑

void

getpath

(treenode root,treenode node,listpath)

if(path.get(path.size()-1)!=node)

if(path.get(path.size()-1)!=node)}}

複雜度分析

時間複雜度:o(n),需要遍歷兩次樹,得到到p和到q的節點,每一次是o(n),加起來也是o(n)

空間複雜度:使用path1,path2儲存路徑,最差情況是o(n),一般情況是o(logn)

劍指Offer68 II 二叉樹的最近公共祖先

不能覆蓋p,q其中乙個是另乙個的祖先的情況 class solution else if l r return true 其中一棵子樹找到了p或q,往上層傳遞 else return false 兩棵廢物子樹,都找不到p,q treenode lowestcommonancestor treenod...

劍指offer 55 II 平衡二叉樹

題目鏈結 輸入一棵二叉樹的根節點,判斷該樹是不是平衡二叉樹。如果某二叉樹中任意節點的左右子樹的深度相差不超過1,那麼它就是一棵平衡二叉樹。示例 1 給定二叉樹 3,9,20,null,null,15,7 3 9 20 15 7 返回 true 示例 2 給定二叉樹 1,2,2,3,3,null,nu...

劍指offer55 II 平衡二叉樹

題目 輸入一棵二叉樹的根節點,判斷該樹是不是平衡二叉樹。分析 平衡二叉樹 balance tree 的定義是 二叉樹中任意節點的左右子樹的深度相差不超過1。注意是任意節點,並不只是根節點的 左深度 右深度 還有其子樹也必須是平衡二叉樹。從該定義也可知是利用遞迴來解決這個問題。class soluti...