树的深度相关题目
以二叉树为例:
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
};
二叉树的深度
思路:
对于根节点来说,就是左右子树中最深的加一。递归的来说,对于当前节点的深度,是其左右子树的最大深度加一,递归边界为(-1),考虑叶节点深度为1,所以空节点为0,即递归边界为0。
代码:
int TreeDepth(TreeNode* root)
{
//递归边界
if(!root) return 0;
int leftDepth = TreeDepth(root->left);
int rightDepth = TreeDepth(root->right);
return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
}
二叉树的直径(即相距最远的两个叶子节点)
错误的思路:将根节点左右子树分离,分别递归的求左右子树的深度然后加和再+2即可,但是下面这种情况显然不是:
正确的思路(附带递归的思考方法):
- 1.传入一个外部引用,用来记录最远距离。
- 2.先考虑根节点计算通过根节点的两个叶节点的最远距离,然后与已经记录的最远距离做比较。(这是较直观的思考递归的方法,先看根节点,再将根节点“泛化”为任意当前节点来考虑)
- 3.同理递归的考虑当前节点,其中通过当前节点的相距最远的两个叶节点的距离,是左右子树的深度+2,因此相对于当前节点递归返回其左右子树的最大深度即可,因此递归边界(要结合返回值以及函数功能来考虑)为-1,因为叶节点到其父节点的距离为1,因此叶节点要初始化为0,故递归至空节点(递归边界)时返回0.
代码:
int Dis(TreeNode* root,int& maxDis)
{
if(!root) reutn -1;
int leftD = Dis(root->left, maxDis) + 1;
int rightD = Dis(root->left, maxDis) +1;
int dist = leftD + rightD;
maxDis = (maxDis > dist ? maxDis : dist);
return (leftD > rightD ? leftD : rightD);
}
判断是否为平衡二叉树
平衡二叉树的定义:任何节点的两颗子树的高度差不能大于一(明显涉及深度问题)
思路:
1.确定函数结构,判断是否为平衡二叉树,故返回值为bool,传入参数为树的根节点,因为要用到深度,所以要额外调用上文的二叉树深度函数。为了面向对象编程,可将其封装成类即:
class solution{
public:
int TreeDepth(TreeNode* root);
bool isBalanced(TreeNode* root);
};
2.先直观考虑根节点,判断其左右子树的高度差不大于一,即需要求左右子树的深度。
3.然后递归的去判断左右子树(递归一开始上述的直观考虑根节点,即被泛化为任意节点)
4.空节点被认为是平衡而c二叉树,因此递归边界返回true;
TreeDepth代码上文有,此处省略,代码一如下:
bool isBalanced(TreeNode* root)
{
if(!root) return true;
return (abs(TreeDepth(root->left) - TreeDepth(root->right)) <= 1 && isBalanced(root->left) && isBalanced(root->right));
}
上述代码虽然简洁易懂,很明显的一个缺点是对于任意节点都要递归求解其深度,为了解决这个问题我们可以传入一个外部引用,记录已经求解的深度。传入外部引用的好处可以让函数多了个”返回值“。
上述代码是从根节点向下递归,每次都递归求解深度,下面的思路是通过叶节点的深度(递归边界)层层向上叠加
class solution{
public:
bool isBalanced(TreeNode* root);
bool isBalanced(TreeNode* root, int& depth);
};
代码二:
class solution{
public:
bool isBalanced(TreeNode* root)
{
int depth = 0;
return isBalanced(root, depth);
}
bool isBalanced(TreeNode* root, int& depth){
if(!root)
{
depth = 0;
return true;
}
//可额外增加此判断代码节省用时,不加也可以
if(!root->right && !root->right)
{
deoth = 1;
return true;
}
int leftD = 0;
int rightD = 0;
bool b1 = isBalanced(root->left, leftD);
bool b2 = isBalanced(root->right,rightD);
depth = (leftD > rightD ? leftD : rightD) + 1;
if(abs(leftD - rightD) <= 1)
return b1&b2;
return false;
}
};