算法学习——LeetCode力扣二叉树篇4(222. 完全二叉树的节点个数、110. 平衡二叉树、257. 二叉树的所有路径、404. 左叶子之和)

本文介绍了如何利用递归方法解决LeetCode中的二叉树问题,包括计算完全二叉树的节点个数,判断高度平衡二叉树,以及找到所有从根到叶子的路径和计算左叶子之和。
摘要由CSDN通过智能技术生成

算法学习——LeetCode力扣二叉树篇4

在这里插入图片描述

222. 完全二叉树的节点个数

222. 完全二叉树的节点个数 - 力扣(LeetCode)

描述

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

示例

示例 1:

输入:root = [1,2,3,4,5,6]
输出:6

示例 2:

输入:root = []
输出:0

示例 3:

输入:root = [1]
输出:1

提示

  • 树中节点的数目范围是[0, 5 * 104]
  • 0 <= Node.val <= 5 * 104
  • 题目数据保证输入的树是 完全二叉树

进阶

遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?

代码解析

递归法–普通二叉树
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     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) {}
 * };
 */
class Solution {
public:
    int getNoteNum(TreeNode* cur)
    {
        if(cur==nullptr) return 0;
        int left_num = getNoteNum(cur->left);
        int right_num = getNoteNum(cur->right);
        return 1 + left_num + right_num;

    }

    int countNodes(TreeNode* root) {
        if(root==nullptr) return 0;
        return getNoteNum(root);
    }
};

递归法–完全二叉树

完全二叉树节点数公式:2^树的高度(深度+1)-1

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     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) {}
 * };
 */
class Solution {
public:
    int getnodenum(TreeNode* cur)
    {
        if(cur==nullptr) return 0 ;
        TreeNode* left_tree = cur->left , *right_tree = cur->right;
        int left_tree_num=0 , right_tree_num=0;
		//分别结算左右树的深度是否一样,一样则是完全二叉树
        while(left_tree!=nullptr)
        {
            left_tree = left_tree->left;
            left_tree_num++;
        }
        while(right_tree!=nullptr)
        {
            right_tree = right_tree->right;
            right_tree_num++;
        }

        if(left_tree_num == right_tree_num )
        {
            //完全二叉树节点数量的公式是2^(树的高度)-1
            // return (2<<left_tree_num) - 1;
            // left_tree_num是树的深度,要+1
            return  pow(2,left_tree_num+1) - 1; 
           
        }else
        {
            return 1 + getnodenum(cur->left) + getnodenum(cur->right) ;
        }
    }
    int countNodes(TreeNode* root) {
        if(root ==nullptr) return 0;
        return getnodenum(root);
    }
};

110. 平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode)

描述

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

示例

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:true

示例 2:

输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

示例 3:

输入:root = []
输出:true

提示

  • 树中的节点数在范围 [0, 5000] 内
  • -104 <= Node.val <= 104

代码解析

求二叉树的深度和高度
深度:前序遍历

  • 深度从根节点往下找,在递归栈增加的时候计算
    高度:后序遍历
  • 高度从叶子节点网上找,在递归栈减少的时候计算
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     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) {}
 * };
 */
class Solution {
public:
	//计算树的高度,后序遍历。当不是平衡二叉树(左右子树高度最多差1)的时候返回-1
    int get_tree_height(TreeNode* cur)
    {
        if(cur==nullptr) return 0;
        
        int left_height = get_tree_height(cur->left);
        if(left_height == -1) return -1;//如果左子树不是平衡二叉树,整个树也不是平衡二叉树
        int right_height =get_tree_height(cur->right);
        if(right_height == -1) return -1;//如果右子树不是平衡二叉树,整个树也不是平衡二叉树
		//两个子树是平衡二叉树,但是不确定整个树是不是平衡二叉树,计算两个树的高度差
		//如果高度差大于1,则不是平衡二叉树。如果高度差是0或者1,则平衡二叉树的高度是最高子树加上根节点1
        return  abs(left_height - right_height) > 1 ? -1 : 1+max(left_height , right_height);

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

257. 二叉树的所有路径

257. 二叉树的所有路径 - 力扣(LeetCode)

描述

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例

示例 1:

输入:root = [1,2,3,null,5]
输出:[“1->2->5”,“1->3”]

示例 2:

输入:root = [1]
输出:[“1”]

提示

  • 树中节点的数目在范围 [1, 100] 内
  • -100 <= Node.val <= 100

代码解析

递归法(非回溯,浪费内存)

直接递归字符串,每一次递归都产生一个新字符串。没有回溯的过程,浪费空间。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     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) {}
 * };
 */
class Solution {
public:
    vector<string> result;
    void get_road(TreeNode* cur  , string &s)
    {
        if(cur == nullptr) return;
        s += to_string(cur->val);
        
        if(cur->left == nullptr && cur->right == nullptr )
        {
            result.push_back(s);
            return;
        }else if(cur->left != nullptr && cur->right == nullptr )
        {   
            s += "->";
            string s1 =s;
            get_road(cur->left ,s1);
        }else if (cur->left == nullptr && cur->right != nullptr )
        {
            s += "->";
            string s1 =s;
            get_road(cur->right ,s1);
        }else
        {
            s += "->";
            string s1 =s;
            string s2 =s;
            get_road(cur->left ,s1);
            get_road(cur->right ,s2);
        }
        return;
       
        
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        string s;
        get_road(root ,s);
        return result;
    }
};

递归回溯法

使用一个数组来保存路径数据,然后在转换成字符串。
效率略低,充分体现回溯的思想。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     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) {}
 * };
 */
class Solution {
public:
    
    void get_road(TreeNode* cur  , vector<string> &result , vector<int> &path)
    {
        if(cur == nullptr) return;
        path.push_back(cur->val);
        
        if(cur->left == nullptr && cur->right == nullptr )
        {
            string tmp;
            for(int i=0 ; i < path.size()-1 ;i++ )
            {
                tmp += to_string(path[i]);
                tmp += "->";
            }
            tmp += to_string(path[path.size()-1]);
            result.push_back(tmp);
            return;
        }
        if(cur->left != nullptr  )
        {   
           get_road(cur->left,result,path);
           path.pop_back();
        } 
        if(cur->right != nullptr)
        {
           get_road(cur->right,result,path);
           path.pop_back();
        }
        return;
       
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result;
        vector<int> path;
        if(root == nullptr) return result;
        get_road(root ,result , path);
        return result;
    }
};

递归回溯(精简版)

不使用数组进行纪录,直接进行字符串回溯

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     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) {}
 * };
 */
class Solution {
public:
    
    void get_road(TreeNode* cur  , vector<string> &result , string path)
    {
        if(cur == nullptr) return;
        path +=  to_string(cur->val);
        
        if(cur->left == nullptr && cur->right == nullptr )
        {
            result.push_back(path);
            return;
        }
        if(cur->left != nullptr  )
        {   
           get_road(cur->left,result, path + "->");
          
        } 
        if(cur->right != nullptr)
        {
           get_road(cur->right,result, path + "->");
           path.pop_back();
        }
        return;
       
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result;
        string path;
        if(root == nullptr) return result;
        get_road(root ,result , path);
        return result;
    }
};

404. 左叶子之和

404. 左叶子之和 - 力扣(LeetCode)

描述

给定二叉树的根节点 root ,返回所有左叶子之和。

示例

示例 1:

输入: root = [3,9,20,null,null,15,7]
输出: 24
解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24

示例 2:

输入: root = [1]
输出: 0

提示

  • 节点数在 [1, 1000] 范围内
  • -1000 <= Node.val <= 1000

代码解析

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     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) {}
 * };
 */
class Solution {
public:
    int result=0;
    void left_sum(TreeNode* cur)
    {
        if(cur==nullptr) return ;
        //判断左子叶
        if(cur->left!=nullptr&&cur->left->left==nullptr&&cur->left->right==nullptr) 
        	result += cur->left->val;
        left_sum(cur->left);
        left_sum(cur->right);

    }
    int sumOfLeftLeaves(TreeNode* root) {
        left_sum(root);
        return result;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉依达的嵌入式小屋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值