代码随想录|递归法二叉树高度和深度

 引入

104 二叉树最大深度

11 二叉树的最小深度

110 平衡二叉树

这几道题本质都是在求二叉树的深度和高度。

什么是二叉树的高度呢?什么是二叉树的深度呢?看了下面这图相信大家就会清楚了。

深度指的是根节点该节点的最长距离。

高度指的是该节点到以其为根节点的子树的叶子节点的最长距离。

 题目分析

 104 求二叉树的最大深度,就是在求根节点到任意一个节点的深度中的最大值,显然,这个最大值一定出现在叶子节点。换个理解方式,这道题就是在求,叶子节点到根节点的最大高度。

二叉树的最大高度 = 二叉树的最大深度 = 根节点到叶子节点的最长距离

 11 求二叉树的最小深度,根据题意,是在求根节点到叶子节点的最小距离

二叉树的最小高度 = 二叉树的最小深度 = 根节点到叶子节点的最小距离

 110 平衡二叉树本质是在求的是每个节点的左右子树的高度。

解题模版

  • 计算高度(后序遍历):遍历到直到叶子节点才开始计算,将结果比较后传给上一个节点,所以每一个节点的高度都应该是其子节点高度加一。至于每一个节点的高度如何计算,就看具体的题意,比如求最大高度,就应该是计算max,如果计算的是最小高度,就应该使用min。
// 最大高度

int getMaxDepth(TreeNode* root){
    if(root==nullptr) return 0;
    return max(getMaxDepth(root->left) + getMaxDepth(root->right) )+ 1;

}

// 最小高度

int minDepth(TreeNode* root) {
    if(root==nullptr) return 0;
    if(root->left==nullptr && root->right!=nullptr) return minDepth(root->right)+1;
    if(root->left!=nullptr && root->right == nullptr) return minDepth(root->left)+1;
        
    return min(minDepth(root->left),minDepth(root->right))+1;
}

至于判断平衡二叉树 ,其实就是判断是否所有节点的左右子树都满足高度差小于1。所以这道题需要用后序遍历,需要从下至上的判断每一个节点的true和false。

如果从上至下判断遇到以下情况,就会直接判断为true了,但这不是平衡树。

int getDepth(TreeNode* root){
    if(root==nullptr) return 0;
    return max(getDepth(root->left),getDepth(root->right))+1;
}
bool isBalanced(TreeNode* root) {
    if(root==nullptr) return true;
    if( abs(getDepth(root->left)-getDepth(root->right))>1) return false;
    
    bool left = isBalanced(root->left);
    bool right = isBalanced(root->right);
    bool balance = left&&right;
    return balance;
}

 下面还有个解法,更加简洁一些。

int getHeight(TreeNode* root){
    if(root==nullptr) return 0;
    int left = getHeight(root->left);
    if(left==-1) return -1;
    int right = getHeight(root->right);
    if(right==-1) return -1;
    return abs(left-right)>1 ? -1 : max(left, right)+1;

}
bool isBalanced(TreeNode* root) {
    return getHeight(root) == -1 ? false : true;
}

 

  • 计算深度(前序遍历):每遇到一个节点深度加一,遇到叶子节点进行“结算”,比较目前结果和之前结果,比较逻辑根据题意确定。
// 最大深度
int result = 0;
void getMaxDepth(TreeNode* root, int depth){
    if(root->left==nullptr && root->right==nullptr) {
        result = max(depth, result);
        return ;
    }
    getMaxDepth(root->left,depth+1);
    getMaxDepth(root->right,depth+1);
    
}

// 最小深度
int result = INT_MAX;
void getMinDepth(TreeNode* root, int depth){
    if(root->left==nullptr && root->right==nullptr){
        result = min(depth, result);
        return ;
    }
    getMinDepth(root->left, depth+1);
    getMinDepth(root->right, depth+1);
}

这里将depth作为参数传入,其实可以写成:

depth+1;
getDepth(root->left);
depth-1;

这表示的是一种回退,所以这里的前序遍历,也是一个回溯的框架。 


下章写一下层序遍历,个人感觉层序遍历yyds,不需要思考很多逻辑or框架,套模版基本可以搞定。

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值