当前位置: 首页 > news >正文

【代码随想录算法训练营——Day15】二叉树——110.平衡二叉树、257.二叉树的所有路径、404.左叶子之和、222.完全二叉树的节点个数

在这里插入图片描述

LeetCode题目链接
https://leetcode.cn/problems/balanced-binary-tree/
https://leetcode.cn/problems/binary-tree-paths/
https://leetcode.cn/problems/sum-of-left-leaves/
https://leetcode.cn/problems/count-complete-tree-nodes/

题解
110.平衡二叉树
在这里插入图片描述
在这里插入图片描述

想到用左子树的高度减右子树的高度,但递归不知道怎么求高度。在求高度的函数里,高度depth放在条件里还是在函数体里重新定义一个变量。用层序遍历求高度行不行?不用递归?
看了题解,首先明确递归终止条件,遇到空结点时高度为0。接着递归得到左右子树的高度,并确定一个规则,就是当遇到的树不是平衡树时,返回-1。但对高度判断的条件又怎么写呢?直接判断是否等于-1。在后面计算result值时,要把当前结点的高度也加上,左右子树的高度的最大值。
通过结点传回的高度为0确定整棵树的高度基点,然后往上返回时都能令符合平衡二叉树结点的”根“结点高度值加1,当某个结点不满足平衡二叉树的要求时,它以及它上面的所有结点高度值都将为-1。-1是个标记,标记本树中出现了不符合平衡二叉树的子树。

257.二叉树的所有路径
知道用回溯的方法写这道题,但不知道怎么放每次的递归条件。答案是当前的路径(因为要回溯)和结果数组(题目要求string)。
自己顺着思路写了一遍代码,小case过了,最后也过了。

404.左叶子之和
想到用递归去做,但是每次判断左叶子的条件不知道怎么定,还有一个思路是对每个左结点打标记,但怎么区分左叶子结点和左普通结点。
于是看题解,从左叶子结点的父结点去判断该结点是否是左叶子结点,这个思路其实我想到了,但一开始觉得麻烦,就没定下来。递归边界要确定,返回的是左叶子结点的值。后续的递归分支写法和110.平衡二叉树很像,但要注意求了赋值了两次同一个值,原因是左子树的值如果求出来了,而左叶子结点如果递归了返回的是0,这时需要在当前判断求左叶子结点的值,并重新赋值覆盖前面的。
有一个录友说,第一个是递归过程,第二个是真的在求叶子结点的值。

222.完全二叉树的节点个数
这一题是我唯一会的一题,用迭代法,任何一种遍历顺序都可以,但用递归法。写成了求叶子结点个数的代码,改了一下要加上当前结点的个数。看了一下题解,跟我写的也差不多。

代码

//110.平衡二叉树
#include <iostream>
using namespace std;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:bool isBalanced(TreeNode* root) {int depth = getHeight(root);if (depth == -1) return false;else return true;}int getHeight(TreeNode* root) {if (root == NULL) return 0;int leftHeight = getHeight(root->left);int rightHeight = getHeight(root->right);if (leftHeight == -1) return -1;if (rightHeight == -1) return -1;if (abs(leftHeight - rightHeight) > 1)return -1;else return 1 + max(leftHeight, rightHeight);}
};int main() {int nums1[30] = { 3,9,20,NULL,NULL,15,7 }, nums2[30] = { 1,2,2,3,3,NULL,NULL,4,4 };TreeNode* root1 = new TreeNode(3);root1->left = new TreeNode(9);root1->right = new TreeNode(20);root1->right->left = new TreeNode(15);root1->right->right = new TreeNode(7);TreeNode* root2 = new TreeNode(1);root2->left = new TreeNode(2);root2->right = new TreeNode(2);root2->left->left = new TreeNode(3);root2->left->right = new TreeNode(3);root2->left->left->left = new TreeNode(4);root2->left->left->right = new TreeNode(4);Solution s;printf("%d", s.isBalanced(root2));return 0;
}
//257.二叉树的所有路径
#include <iostream>
#include <vector>
#include <string>
using namespace std;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> binaryTreePaths(TreeNode* root) {vector<string> result;vector<int> path;if (root == NULL) return result;path.push_back(root->val);travelsal(root, path, result);return result;}void travelsal(TreeNode* cur, vector<int> &path, vector<string> &result) {if (cur->left == NULL && cur->right == NULL) {string sPath;for (int i = 0;i < path.size() - 1;i++) {sPath += to_string(path[i]);sPath += "->";}sPath += to_string(path[path.size() - 1]);result.push_back(sPath);}if (cur->left) {path.push_back(cur->left->val);travelsal(cur->left, path, result);path.pop_back();}if (cur->right) {path.push_back(cur->right->val);travelsal(cur->right, path, result);path.pop_back();}}
};int main() {int nums1[30] = { 1,2,3,NULL,5 }, nums2[30] = { 1 };TreeNode* root1 = new TreeNode(1);root1->left = new TreeNode(2);root1->right = new TreeNode(3);root1->left->right = new TreeNode(5);TreeNode* root2 = new TreeNode(1);Solution s;vector<string> result = s.binaryTreePaths(root2);for (int i = 0;i < result.size();i++) {cout << result[i] << " " << endl;}return 0;
}
//404.左叶子之和
#include <iostream>
using namespace std;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 sumOfLeftLeaves(TreeNode* root) {if (root == NULL) return 0;if (root->left == NULL && root->right == NULL) return 0;int leftValue = sumOfLeftLeaves(root->left);if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {leftValue = root->left->val;}int rightValue = sumOfLeftLeaves(root->right);return leftValue + rightValue;}
};int main() {int nums1[30] = { 3,9,20,NULL,NULL,15,7 }, nums2[30] = { 1 };TreeNode* root1 = new TreeNode(3);root1->left = new TreeNode(9);root1->right = new TreeNode(20);root1->right->left = new TreeNode(15);root1->right->right = new TreeNode(7);TreeNode* root2 = new TreeNode(1);Solution s;printf("%d", s.sumOfLeftLeaves(root2));return 0;
}
//222.完全二叉树的节点个数
#include <iostream>
using namespace std;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 countNodes(TreeNode* root) {if (root == NULL) return 0;if (root->left == NULL && root->right == NULL) return 1;int leftNum = countNodes(root->left);int rightNum = countNodes(root->right);return leftNum + rightNum + 1;}
};int main() {int nums1[30] = { 1,2,3,4,5,6 }, nums2[30] = {}, nums3[30] = {1};TreeNode* root1 = new TreeNode(1);root1->left = new TreeNode(2);root1->right = new TreeNode(3);root1->left->left = new TreeNode(4);root1->left->right = new TreeNode(5);root1->right->left = new TreeNode(6);TreeNode* root2 = nullptr;TreeNode* root3 = new TreeNode(1);Solution s;printf("%d", s.countNodes(root3));return 0;
}

文章转载自:

http://aVPNotoi.kjynz.cn
http://1FqXAWyp.kjynz.cn
http://HguyAhGY.kjynz.cn
http://gH8wCm1E.kjynz.cn
http://TVzT1ecU.kjynz.cn
http://FMRJkuRf.kjynz.cn
http://k3JYmjnC.kjynz.cn
http://nHk0jI3j.kjynz.cn
http://5RhFMhrf.kjynz.cn
http://jEy80gDb.kjynz.cn
http://aO0bMA9F.kjynz.cn
http://htlIMOsY.kjynz.cn
http://Z0erqVsj.kjynz.cn
http://6wuLzrbM.kjynz.cn
http://fI5wd41L.kjynz.cn
http://REpbnYSr.kjynz.cn
http://1iPGxBiC.kjynz.cn
http://Rsy0saWG.kjynz.cn
http://XVmHrDrQ.kjynz.cn
http://wm7Zxz9a.kjynz.cn
http://guaSUY1N.kjynz.cn
http://K5YHpnli.kjynz.cn
http://UNidEvHX.kjynz.cn
http://Q4Ys9Lm2.kjynz.cn
http://5LurtYQZ.kjynz.cn
http://qCS3u4JJ.kjynz.cn
http://TgUSJyJ2.kjynz.cn
http://ydba9fIA.kjynz.cn
http://G4mrBuS2.kjynz.cn
http://BgYWhecx.kjynz.cn
http://www.dtcms.com/a/387421.html

相关文章:

  • 《从终端到内核:Linux 指令体系的入门与技术解构(第二篇)》
  • 实验5:组件应用(4学时)
  • 精选40道Kafka面试
  • web自动化随笔
  • HarmonyOS 多线程编程:Worker 使用与性能优化指南
  • 卫星通信大爆发:未来,你的手机将不再“失联”
  • 带你了解STM32:EXTI外部中断
  • Charles抓包工具新手入门教程 安装配置、手机代理与基础使用指南
  • 鸿蒙智能设备自动诊断实战:从传感器采集到远程上报的完整实现
  • 第五章 Arm C1-Premium 内存管理单元详解
  • 第七章 Arm C1-Premium L1数据内存系统解析
  • ARM(10) - I2C
  • 计算机视觉(opencv)实战二十六——背景建模与运动目标检测
  • 《详解Maven的继承与聚合》一篇理解分模块设计理念,以及私服的使用
  • Linux系统服务Syslog服务
  • 985高校标杆项目:基于大数据的商店销售数据分析与可视化系统技术解析
  • OpenCV内置分类器实现简单的人脸识别
  • 基于vue社区养老管理系统3849x(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 破解云VR教育普及难题:点量实时云渲染——实现跨终端无界协同
  • 智能合约安全常见攻击与防御
  • Docker多容器编排:Compose 实战教程
  • StarRocks 助力数禾科技构建实时数仓:从数据孤岛到智能决策
  • 重构多任务爬虫
  • 语音DDS系统核心组件详解与实现方案
  • 部署CephFS文件存储
  • 元宇宙与物流产业:数字孪生重构物流全链路运营
  • 通信算法之328:Vivado中FIFO的IP核
  • Android MediaCodec 编解码
  • Resolve JSON Reference for ASP.NET backend
  • 十一、vue3后台项目系列——封装请求,存储token,api统一化管理,封装token的处理工具