平衡二叉树的定义为:给定一个二叉树,每个节点的左右两个子树的高度差绝对值不超过 1 ,同时左右子树也满足上述条件。
如:
给定二叉树 [3, 9, 20, null, null, 15, 7] 3 / 9 20 / 15 7 根节点的左右子树高度差为1,值为20的子树的左右子树高度差为0,因此返回 true。
而:
给定二叉树 [1,2,2,3,3,null,null,4,4] 1 / 2 2 / 3 3 / 4 4 根节点的左右子树高度差为2,因此返回 false。
这里要解释一下二叉树高度和深度的定义:
二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。
二叉树节点的高度:指从该节点到叶子节点(没有左右子树的节点)的最长简单路径边的条数。
求深度可以从上到下的方式计算,因此使用前序遍历(中左右),求高度则需要使用从下到上的方式,因此使用后序遍历(左右中)。
了解遍历方式之后,我们采用递归来解决此问题:
二叉树树节点定义:
struct TreeNode{ TreeNOde* left; TreeNode* right; int val; 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) {} }
一、自上而下(前序遍历)
递归三部曲:
1.确定输入参数:本题需要计算树节点高度,输入树节点指针即可,不需要其他参数, 返回节点高度。即 int getHeight(TreeNode* node);
2.确定终止条件:当遍历到空节点时,高度为0,终止递归。即:if(node == NULL) return 0;
3.单步逻辑:
int geHeight(TreeNode* node){ if(node == NULL) return 0; int leftH = getHeight(node->left); int rightH = getHeight(node->right); return max(leftH, rightH)+1; }
整体c++代码:
class Solution{ public: int geHeight(TreeNode* node){ if(node == NULL) return 0; int leftH = getHeight(node->left); int rightH = getHeight(node->right); return max(leftH, rightH)+1; //获取最大高度 } int isBalanced(TreeNode* root){ if(node == NULL) return true; int leftH = getHeight(root->left); //左子树最大高度 int right = getHeight(root->right); //右子树最大高度 //左右子树高度差小于2并且左右子树都是平衡二叉树,整体才是平衡二叉树 return abs(leftH-rightH)<2 && isBalanced(root->left) && isBalanced(root->right); } }
二、自下而上(后序遍历)
上述方法有一个弊端,即:
对于节点 p,如果它的高度是 d,则 getHeight§ 最多会被调用 d 次(即遍历到它的每一个祖先节点)。
自下而上递归的做法类似于后序遍历,对于当前遍历到的节点,先递归地判断其左右子树是否平衡,再判断以当前节点为根的子树是否平衡。如果一棵子树是平衡的,则返回其高度(高度一定是非负整数),否则返回 −1。如果存在一棵子树不平衡,则整个二叉树一定不平衡。
递归三部曲:
1.确定输入参数:本题需要计算树节点高度,输入树节点指针即可,不需要其他参数, 返回节点高度。即 int getHeight(TreeNode* node);
2.确定终止条件:当遍历到空节点时,高度为0,终止递归。即:if(node == NULL) return 0;
3.单步逻辑:
class Solution{ public: int geHeight(TreeNode* node){ if(node == NULL) return 0; int leftH = getHeight(node->left); if(leftH == -1) return -1; //当左子树不是平衡二叉树时,提前返回 int rightH = getHeight(node->right); if(rightH == -1) return -1;//当右子树不是平衡二叉树时,也提前返回 return abs(leftH-rightH)>1?-1:max(leftH, rightH)+1; //当高度差大于1,返回-1,否则返回最大高度 } int isBalanced(TreeNode* root){ return getHeight(root)==-1?false:true;//当返回-1时说明不是平衡二叉树,否则是平衡二叉树 } }
参考:
1.https://leetcode-cn.com/problems/balanced-binary-tree/solution/ping-heng-er-cha-shu-by-leetcode-solution/
2.https://zhuanlan.zhihu.com/p/263037657
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)