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

news2025/1/20 12:12:56

算法学习——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;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1455209.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入浅出熟悉OpenAI最新大作Sora文生视频大模型

蠢蠢欲动&#xff0c;惴惴不安&#xff0c;朋友们我又来了&#xff0c;这个春节真的过的是像过山车&#xff0c;Gemini1.5 PRO还没过劲&#xff0c;OpenAI又放大招&#xff0c;人类真的要认输了吗&#xff0c;让我忍不住想要再探究竟&#xff0c;到底是什么让文生视频发生了质的…

C语言—字符数组(3)

可能不是那么的完整&#xff0c;先凑合看吧&#xff0c;如果我学会如何修改以后&#xff0c;我慢慢回来修改的 1.编写程序实现对两个字符串的连接功能&#xff1b; 法一:不使用strcat函数,写程序直接实现&#xff0c;记得添加结束符&#xff0c;不然程序访问数组时候将变得不…

算法基础——单调栈,单调队列

目录 1.单调栈 例题&#xff1a;【模板】单调栈 例题:求和 2.单调队列 例题&#xff1a;滑动窗口 1.单调栈 例题&#xff1a;【模板】单调栈 可以想象出一个柱状图&#xff0c;值越大&#xff0c;这个柱子越高 以此题的样例为例&#xff1a; 第一个数为7&#xff0c;想…

.ma1x0勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复

尊敬的读者&#xff1a; 数据安全问题备受关注。而勒索病毒是其中一种最为恶劣的威胁之一。其中&#xff0c;.ma1x0勒索病毒备受人们担忧&#xff0c;因其可将用户的数据文件加密&#xff0c;并要求支付赎金以解密文件。本文将介绍.ma1x0勒索病毒的特征、预防方法以及如何恢复…

GIS分析和摄影测量进行屋顶太阳能潜力评估

目前,不可再生的能源资源有限,而减少全球变暖的想法使可再生能源的利用成为当务之急。其中,太阳能作为最清洁、最丰富的可再生能源备受关注。此外,成本的日益降低也使太阳能成为一种极具吸引力的能源。然而,为了从太阳能中获得最大利益,必须考虑各种标准,并选择合适的区…

SG3225EAN规格书

SG3225EAN 晶体振荡器利用先进的锁相环技术和AT切割晶体单元&#xff0c;提供了宽频率范围和高性能LV-PECL输出&#xff0c;73.5 MHz至700 MHz的宽频率范围&#xff0c;能够保证高稳定性和宽频率调整的能力&#xff0c;适应于多样化的应用需求。2.5V和3.3V两种供电电压&#xf…

Spring 用法学习总结(四)之 JdbcTemplate 连接数据库

&#x1f409;目录 9 JdbcTemplate 9 JdbcTemplate Spring 框架对 JDBC 进行了封装&#xff0c;使用 JdbcTemplate 方便实现对数据库操作 相关包&#xff1a; 百度网盘链接https://pan.baidu.com/s/1Gw1l6VKc-p4gdqDyD626cg?pwd6666 创建properties配置文件 &#x1f4a5;注意…

Stackoverflow(1)-根据RequestBody的内容来区分使用哪个资源

如果使用Spring&#xff0c;可以通过RequestBody将请求体的json转换为Java对象&#xff0c;但如果URI相同&#xff0c;而请求体的内容不同&#xff0c;应该怎么办&#xff1f;问题来源(stackoverflow)&#xff1a;Spring RequestBody without using a pojo?稍微研究了一下&…

vue-router 实现路由懒加载

在现代的Web开发中&#xff0c;前端技术的发展日新月异。在构建大规模单页应用&#xff08;Single Page Application&#xff09;时&#xff0c;路由管理是一个非常重要的环节。随着用户对网页速度和性能的要求越来越高&#xff0c;有效的路由管理能够显著提升用户体验。本篇博…

torch.utils.data

整体架构 平时使用 pytorch 加载数据时大概是这样的&#xff1a; import numpy as np from torch.utils.data import Dataset, DataLoaderclass ExampleDataset(Dataset):def __init__(self):self.data [1, 2, 3, 4, 5]def __getitem__(self, idx):return self.data[idx]def…

GitKraken Create Repository and Clone不可点击

问题 GitKraken Create Repository and Clone不可点击 详细问题 笔者第一次使用GitKraken&#xff0c;在创建仓库时&#xff0c;填写完成仓库初始化后。发现Create Repository and Clone不可点击。 解决方案 选择Where to clone to位置 产生原因 在创建仓库时&#xff0…

IO 作业 24/2/18

1> 使用fgets统计给定文件的行数 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, const char *argv[]) {//定义文件指针FILE *fpNULL;//打开文件&#xff08;只读&#xff09;if((fpfopen("./test.txt",&quo…

机器人内部传感器-位置传感器-电位器式位置传感器

位置传感器 位置感觉是机器人最基本的感觉要求&#xff0c;可以通过多种传感器来实现。位置传感器包括位置和角度检测传感器。常用的机器人位置传感器有电位器式、光电式、电感式、电容式、霍尔元件式、磁栅式及机械式位置传感器等。机器人各关节和连杆的运动定位精度要求、重…

suse15 sp3-sp5离线安装中安装FIO

没有网络的情况下&#xff0c;离线安装相对比较困难一点&#xff0c;所有需要提前下载相应的RPM安装包 FIO 安装包链接如下&#xff1a; Install package benchmark / fio 正常安装的时候&#xff0c;会出现问题 如下&#xff1a; google下 https://opensuse.pkgs.org/15.5/…

WorkPlus Meet助力企业建立安全可靠的私有化视频会议平台

企业需要保护敏感信息和保证会议质量的同时&#xff0c;提高会议的效率和协作水平。作为一款私有化视频会议软件系统&#xff0c;WorkPlus Meet以其卓越的性能和高度私密的特性&#xff0c;助力企业打造安全可靠的私有化视频会议平台。 为何选择WorkPlus Meet作为私有化视频会议…

软件实例分享,酒店酒水寄存管理系统软件教程

软件实例分享&#xff0c;酒店酒水寄存管理系统软件教程 一、前言 以下软件教程以 佳易王酒水寄存管理系统软件V16.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、寄存的商品名称可以预先设置 2、寄存人可以使用手.机号识别 3、会员充值…

flowpilot Pxiel 6 redmi K30 Pro

Installation flowdriveai/flowpilot Wiki GitHub Flowpilot can be installed on: Android phone Non-rooted running Android 10Android 11Android 12Rooted running Android 13 requires rootDesktop pc with Ubuntu > 20.04. 安装Termux https://f-droid.org/repo…

Sentinel从入门到“精通”,从源码层面学习Sentinel

B站视频讲解 文章目录 一、安装1、原生使用2、dashboard整合2-1、非starter整合2-1-1、公共2-1-2、Filter2-1-3、AOP2-2、starter 整合 3、总结 二、常见的策略1、限流1-1、基于QPS 限流1-2、基于线程数限流 2、降级2-1、慢调用比例2-2、异常数&#xff08;限流异常不算&#x…

《游戏引擎架构》--学习

内存管理 优化动态内存分配 维持最低限度的堆分配&#xff0c;并且永不在紧凑循环中使用堆分配 容器 迭代器 未完待续。。。

深度学习与计算机视觉 | 实用CV开源项目汇总(有github代码链接,建议收藏!)

本文来源公众号“深度学习与计算机视觉”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;【建议收藏】实用CV开源项目汇总&#xff08;文末有彩蛋~&#xff09; 01 Trace.moe 图像反向搜索动漫场景&#xff0c;使用动漫截图搜索该…