如何判斷是否爲平衡二叉樹?node
答:每一個節點的左右子樹高度差的絕對值小於等於1,咱們認爲該二叉樹平衡;算法
只要有一個節點的左右子樹高度差絕對值大於1,咱們認爲這顆二叉樹不平衡。函數
所以,判斷一棵樹是否平衡,須要計算樹的高度以及判斷高度差。spa
下面介紹兩種判斷平衡二叉樹的方式:自頂向下,自底向上。code
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */
int getHeight(TreeNode* root){ if(root爲空節點) return 0; return 左子樹與右子樹的最大高度+1; } bool isBalanced(TreeNode* root){ if(root爲空節點) return ture; if(左子樹爲平衡樹且右子樹爲平衡樹) if(左子樹與右子樹的高度差小於2) return true; return false; }
int getHeight(TreeNode* root){ if(root==NULL) return 0; return max(getHeight(root->right),getHeight(root->left))+1; } bool isBalanced(TreeNode* root) { if(root==NULL) return true; if(isBalanced(root->left)&&isBalanced(root->right)) if(abs(getHeight(root->left)-getHeight(root->right))<2) return true; return false; }
\[ O(n\log n) \]get
\[ O(n) \]it
這不是最優算法,出現了不少冗餘計算,getHeight
函數顯然要被重複調用不少次。計算每個節點的時候,都重複計算了子節點的高度,浪費計算機算力,重複計算已經計算過的結果顯然是不合適的。io
解決的辦法也呼之欲出,將每次計算出的高度傳出來保存不就行了?class
因而有了下面自底向上的方法。這樣能夠充分利用每次計算的高度的結果,下降計算量。二叉樹
int isBalancedHelper(TreeNode* root,int& height){ if(root爲空節點){ height=0; return true; } int left,right; if(判斷右子樹是不是平衡數並把高度賦給right&&判斷左子樹是不是平衡數並把高度賦給left) if(left與right的差的絕對值小於2){ height=left與right的最大值+1; return true; } return false; } bool isBalanced(TreeNode* root) { int height=0; return isBalancedHelper(root,height); }
int isBalancedHelper(TreeNode* root,int& height){ if(root==NULL){ height=0; return true; } int left,right; if(isBalancedHelper(root->right,right)&&isBalancedHelper(root->left,left){ if(abs(left-right)<2)){ height=max(left,right)+1; return true; } } return false; } bool isBalanced(TreeNode* root) { int height=0; return isBalancedHelper(root,height); }
\[ O(n) \]
\[ O(n) \]
自底向上每次判斷都把高度傳了出去,而且每一次計算都充分利用子節點的高度數據,沒有進行重複計算,在不提高空間複雜度的狀況下,下降了整個算法的時間複雜度。