【题目描述】
输入一棵二叉树的根节点,判断该二叉树是否是平衡二叉树。如果某二叉树中的任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树(AVL树)。
【代码实现】
实现一:需要重复遍历节点多次,简单但是不足以打动面试官
1 /* 2 struct TreeNode { 3 int val; 4 struct TreeNode *left; 5 struct TreeNode *right; 6 TreeNode(int x) : 7 val(x), left(NULL), right(NULL) { 8 } 9 };*/ 10 class Solution { 11 public: 12 int TreeDepth(TreeNode* pRoot) 13 { 14 if(pRoot==NULL) 15 return 0; 16 else 17 { 18 int leftLength=TreeDepth(pRoot->left); 19 int rightLength=TreeDepth(pRoot->right); 20 return leftLength>rightLength?(leftLength+1):(rightLength+1); 21 } 22 } 23 24 bool IsBalanced_Solution(TreeNode* pRoot) { 25 if(pRoot==NULL) 26 return true; 27 int leftLength=TreeDepth(pRoot->left); 28 int rightLength=TreeDepth(pRoot->right); 29 int diff=leftLength>rightLength?leftLength-rightLength:rightLength-leftLength; 30 if(diff>1) 31 return false; 32 33 return IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right); 34 } 35 };
点评:上述代码固然简单,但是除根节点外其余每个节点都要被遍历多次,这种思路的时间效率不是很高,只能是差强人意。
实现二:每个节点只需要遍历一次,面试官的最爱
1 /* 2 struct TreeNode { 3 int val; 4 struct TreeNode *left; 5 struct TreeNode *right; 6 TreeNode(int x) : 7 val(x), left(NULL), right(NULL) { 8 } 9 };*/ 10 class Solution { 11 public: 12 bool JudgeBalanced(TreeNode* pRoot,int * depth) 13 { 14 if(pRoot==NULL) 15 { 16 *depth=0; 17 return true; 18 } 19 20 int leftLength=0; 21 int rightLength=0; 22 if(JudgeBalanced(pRoot->left,&leftLength)&&JudgeBalanced(pRoot->right,&rightLength)) 23 { 24 int diff=leftLength>rightLength?leftLength-rightLength:rightLength-leftLength; 25 if(diff<=1) 26 { 27 *depth=leftLength>rightLength?leftLength+1:rightLength+1; 28 return true; 29 } 30 } 31 32 return false; 33 } 34 35 bool IsBalanced_Solution(TreeNode* pRoot) { 36 int depth=0; 37 return JudgeBalanced(pRoot,&depth); 38 } 39 };
点评:如果我们用后序遍历的方式遍历二叉树的每个节点,在遍历到一个节点之前我们就已经遍历了它的左右子树。只要在遍历每个节点的时候记录它的深度(某一节点的深度等于它到叶子节点路径的最大长度),我们就可以一边遍历一边判断每个节点是不是平衡的。
从下往上,从左向右判断二叉树的平衡性。