No. 110 - Balanced Binary Tree ==== ![Problem](https://img.shields.io/badge/problem-tree-blue) ![Difficulty](https://img.shields.io/badge/difficulty-easy-brightgreen) --- ## [LeetCode 110 -- Balanced Binary Tree](https://leetcode.com/problems/balanced-binary-tree/) ### 題目描述 Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as: >a binary tree in which the left and right subtrees of every node differ in height by no more than 1. Example 1. ![](https://i.imgur.com/enNDyoa.jpg) ``` Input: root = [3,9,20,null,null,15,7] Output: true ``` Example 2. ![](https://i.imgur.com/C4F3RQl.jpg) ``` Input: root = [1,2,2,3,3,null,null,4,4] Output: false ``` --- 本題目的是要檢查給定的 tree,它每個 node 的左右 subtree 是不是平衡。這邊平衡的意思就是左右 subtree 的高相差不超過 1。 ### 解法 要比較每個 node 的左右 subtree 是不是平衡的,我們需要先算出它們的高,接著再把他們彼此相減比較是否平衡。 我們設計一個函式如下: ```cpp bool _isBalanced(TreeNode *node, int &height); ``` 它的回傳值是 boolean 值,目的是回傳當前 `node` 的左右 subtree 是否平衡,並且帶有另外一個參數 `height` 來知道當前的 subtree 的高。 這個函式的做法如下: ```cpp= bool _isBalanced(TreeNode *root, int &height) { if (!root) return true; int lh = 0; int rh = 0; if (!_isBalanced(root->left, lh) || // check if left subtree is balanced. !_isBalanced(root->right, rh)) // check if right subtree is balanced. return false; // if subtree is unbalanced, then the tree is unbalanced. height = max(lh, rh) + 1; // calculate tree height return abs(lh - rh) <= 1; // compare that if current subtree is balanced. } ``` 此函式的第 6 行會 recursive 的去確認每個 node 的左右 subtree 是否平衡,也就是會從 leaf 開始 bottom up 的比對每一層 tree node 的 subtree 是否平衡。一旦發現有個 node 的 subtree 不平衡,那整個 tree 就是不平衡。 倘若左右 subtree 都是平衡的,第 9 行就會算出當前 subtree 的高,並且第 10 行會比較這個 subtree 是否是平衡的。 完整程式碼如下: ```cpp= /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: bool _isBalanced(TreeNode *root, int &height) { if (!root) return true; int lh = 0; int rh = 0; if (!_isBalanced(root->left, lh) || // check if left subtree is balanced. !_isBalanced(root->right, rh)) // check if right subtree is balanced. return false; // if subtree is unbalanced, then the tree is unbalanced. height = max(lh, rh) + 1; // calculate tree height return abs(lh - rh) <= 1; // compare that if current subtree is balanced. } bool isBalanced(TreeNode* root) { int height = 0; return _isBalanced(root, height); } }; ``` ### 複雜度分析 這個 recursive 的作法是 one pass 完成比較平衡並且同時計算 tree 高,所以 `_isBalanced` 函式被呼叫的次數就是 node 的數量,時間複雜度為 $O(N)$。 空間複雜度上為 $O(H)$, $H$ 為 tree 的高。