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

算法学习——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是树的深度,要+1return  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)的时候返回-1int 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,则平衡二叉树的高度是最高子树加上根节点1return  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.hqwc.cn/news/467355.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux学习】线程互斥与同步

目录 二十.线程互斥 20.1 什么是线程互斥&#xff1f; 20.2 为什么需要线程互斥? 20.3 互斥锁mutex 20.4 互斥量的接口 20.4.1 互斥量初始 20.4.2 互斥量销毁 20.4.3 互斥量加锁 20.4.4 互斥量解锁 20.4.5 互斥量的基本原理 20.4.6 带上互斥锁后的抢票程序 20.5 死锁问题 死锁…

离散数学截图

二元运算及其性质 二元运算中的特殊元 半群和独异点 代数系统的同态与同构 下确界是最大的下界&#xff0c;而在4、5、6三个下界里面&#xff0c;4和5都比6大。可4和5之间没办法分出大小&#xff0c;所以这个哈斯图没有下确界

1921:【02NOIP普及组】过河卒

1921&#xff1a;【02NOIP普及组】过河卒 【题目描述】 如图&#xff0c;A点有一个过河卒&#xff0c;需要走到目标B点。卒行走的规则&#xff1a;可以向下、或者向右。 同时在棋盘上的任一点有一个对方的马&#xff08;如上图的C点&#xff09;&#xff0c;该马所在的点和所有…

【从Python基础到深度学习】2. Ubuntu及插件安装

本期所有软件安装包&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1UVEYm-12FivAnrE5NUXevg?pwdum60 一、安装Ubuntu 1.1 软件安装包&#xff1a;下载 VMware Workstation Pro | CN 一直点下一步即可 1.2 双击运行软件&#xff1a; 输入密钥 1 、VMware 15密钥 …

B2084 质因数分解

题目描述 已知正整数 n 是两个不同的质数的乘积&#xff0c;试求出较大的那个质数。 输入格式 输入只有一行&#xff0c;包含一个正整数 n&#xff08;6<n<&#xff09;。 输出格式 输出只有一行&#xff0c;包含一个正整数 p&#xff0c;即较大的那个质数。 输入输…

JS游戏项目合集【附源码】

文章目录 一&#xff1a;迷宫小游戏二&#xff1a;俄罗斯方块三&#xff1a;压扁小鸟 一&#xff1a;迷宫小游戏 【迷宫游戏】是一款基于HTML5技术开发的游戏&#xff0c;玩法简单。玩家需要在一个迷宫中找到出口并成功逃脱&#xff0c;本项目还有自动寻路&#xff08;Track&a…

LeetCode、435. 无重叠区间【中等,贪心 区间问题】

文章目录 前言LeetCode、435. 无重叠区间【中等&#xff0c;贪心 区间问题】题目链接及分类思路贪心、区间问题 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技…

【白话前端】快速区分webGL,webGPU,unity3D和UE4

在3D图形渲染的渲染领域&#xff0c;很多友友们对上述概念傻傻分不清&#xff0c;站在前端开发角度&#xff0c;我用简单语言说下&#xff0c;结论在文章最后。 一、四者都能进行3D图形渲染 它们之间有一些区别&#xff0c;下面我将对它们进行简单的区分&#xff1a; WebGPU&a…

【Vue】computed与watch

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Vue⛺️稳重求进&#xff0c;晒太阳 计算属性 概念&#xff1a;基于现有的数据&#xff0c;计算出来新的属性&#xff0c;依赖的数据变化&#xff0c;自动重新计算 语法&#xff1a; 声明…

Linux下的socket操作

一、TCP服务端 创建一个TCP服务器的基本操作&#xff1a; 创建一个套接字&#xff08;socket&#xff09;&#xff1a;使用socket函数绑定套接字&#xff08;socket&#xff09;:将套接字绑定到一个特定的IP地址和端口号上&#xff0c;这些信息要用结构体sockaddr_in来保存监…

Java+SpringBoot实习管理系统探秘

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

车载诊断协议DoIP系列 —— DoIP应用(Application)需求

车载诊断协议DoIP系列 —— DoIP应用(Application)需求 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师(Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一…