如何判断是否为平衡二叉树?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) \]
自底向上每次判断都把高度传了出去,而且每一次计算都充分利用子节点的高度数据,没有进行重复计算,在不提高空间复杂度的状况下,下降了整个算法的时间复杂度。