LeetCode 110. 平衡二叉樹 | Python
阿新 • • 發佈:2020-08-17
110. 平衡二叉樹
題目來源:力扣(LeetCode)https://leetcode-cn.com/problems/balanced-binary-tree
題目
給定一個二叉樹,判斷它是否是高度平衡的二叉樹。
本題中,一棵高度平衡二叉樹定義為:
一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過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。
也就是說,只有所有子樹都是平衡二叉樹的條件下,整個二叉樹才是平衡二叉樹。那麼我們用遞迴的思想來解決這個問題。
遞迴(自頂向下)
在這裡,我們先用自頂向下的思路來去解決這個問題。
上面說了,要判斷一個二叉樹是否是平衡二叉樹?要看所有子樹是否都是平衡二叉樹,那麼這裡需要比較每個節點左右子樹的高度差絕對值,不能超過 1。
那麼,首先考慮計算節點的高度 height,會有以下情況:
- 若當前節點為空節點,那麼返回高度 0;
- 若當前節點為非空節點,那麼這裡返回左右子樹中的最大高度 + 1。
然後,要考慮的是如何去判斷是否平衡?情況如下:
- 先處理特殊情況,如果根節點為空,直接返回 True;
- 根節點非空,那麼這裡用先序遍歷遞迴,對下面三種情況進行判斷:
- 判斷當前子樹是否是平衡二叉樹;
- 判斷當前子樹的左子樹是否是平衡二叉樹;
- 判斷當前子樹的右子樹是否是平衡二叉樹。
具體的程式碼見【程式碼實現 # 遞迴(自頂向下)】
遞迴(自底向上)
在上面 遞迴(自頂向下) 的方法中,會產生大量重複計算,時間複雜度較高。
這裡具體的做法如下:
- 設定終止條件:
- 越過葉子節點時,返回高度 0;
- 若左右子樹任一高度為 -1 的情況下,代表左右子樹不平衡,直接返回 -1。(這裡左右子樹高度由下面的左右子樹高度差絕對值是否超過 1 決定)
- 如果當前節點左右子樹的高度差的絕對值不超過 1 時,那麼返回左右子樹最大高度 +1;
- 如果當前節點左右子樹的高度差的絕對值超過 1 時,返回 -1,表示子樹不平衡。
具體的程式碼見【程式碼實現 # 遞迴(自底向上)】
程式碼實現
# 遞迴(自頂向下)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def depth(root):
"""求當前節點的深度
Args:
root: 節點
Returns:
返回節點深度
"""
# 節點為空,返回高度 0
if not root:
return 0
# 否則返回左右子樹最大高度值 +1
return max(depth(root.left), depth(root.right)) + 1
# 根節點為空,直接返回 True
if not root:
return True
# 否則遞迴判斷
# 1. 當前子樹是否平衡
# 2. 當前子樹左子樹是否平衡
# 3. 當前子樹右子樹是否平衡
return abs(depth(root.left)-depth(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)
# 遞迴(自底向上)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def helper(root):
if not root:
return 0
left = helper(root.left)
# 當左右子樹高度為 -1,表示不平衡返回 -1
if left == -1:
return -1
right = helper(root.right)
if right == -1:
return -1
# 判斷左右子樹高度差的絕對值是否不超過 1
return -1 if abs(left-right) > 1 else max(left, right) + 1
return helper(root) >= 0
實現結果
歡迎關注
公眾號 【書所集錄】