每日算法:平衡二叉樹
本文轉載自微信公眾號「三分鐘學前端」,作者sisterAn 。轉載本文請聯系三分鐘學前端公眾號。
關于樹基礎看這里:適合初學者的樹
給定一個二叉樹,判斷它是否是高度平衡的二叉樹。
本題中,一棵高度平衡二叉樹定義為:
一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過1。
示例 1:
給定二叉樹 [3,9,20,null,null,15,7]
- 3
- / \
- 9 20
- / \
- 15 7
返回 true 。
示例 2:
給定二叉樹 [1,2,2,3,3,null,null,4,4]
- 1
- / \
- 2 2
- / \
- 3 3
- / \
- 4 4
返回 false 。
解答一:自頂向下(暴力法)
解題思路: 自頂向下的比較每個節點的左右子樹的最大高度差,如果二叉樹中每個節點的左右子樹最大高度差小于等于 1 ,即每個子樹都平衡時,此時二叉樹才是平衡二叉樹
代碼實現:
- const isBalanced = function (root) {
- if(!root) return true
- return Math.abs(depth(root.left) - depth(root.right)) <= 1
- && isBalanced(root.left)
- && isBalanced(root.right)
- }
- const depth = function (node) {
- if(!node) return -1
- return 1 + Math.max(depth(node.left), depth(node.right))
- }
復雜度分析:
- 時間復雜度:O(nlogn),計算 depth 存在大量冗余操作
- 空間復雜度:O(n)
解答二:自底向上(優化)
解題思路: 利用后續遍歷二叉樹(左右根),從底至頂返回子樹最大高度,判定每個子樹是不是平衡樹 ,如果平衡,則使用它們的高度判斷父節點是否平衡,并計算父節點的高度,如果不平衡,返回 -1 。
遍歷比較二叉樹每個節點 的左右子樹深度:
- 比較左右子樹的深度,若差值大于 1 則返回一個標記 -1 ,表示當前子樹不平衡
- 左右子樹有一個不是平衡的,或左右子樹差值大于 1 ,則二叉樹不平衡
- 若左右子樹平衡,返回當前樹的深度(左右子樹的深度最大值 +1 )
代碼實現:
- const isBalanced = function (root) {
- return balanced(root) !== -1
- };
- const balanced = function (node) {
- if (!node) return 0
- const left = balanced(node.left)
- const right = balanced(node.right)
- if (left === -1 || right === -1 || Math.abs(left - right) > 1) {
- return -1
- }
- return Math.max(left, right) + 1
- }
復雜度分析:
- 時間復雜度:O(n)
- 空間復雜度:O(n)