首页 > 编程语言 >代码随想录算法训练营第十七天| 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和

代码随想录算法训练营第十七天| 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和

时间:2023-08-17 09:57:37浏览次数:41  
标签:随想录 叶子 404 二叉树 path root 节点 left

 卡哥建议:迭代法,大家可以直接过,二刷有精力的时候 再去掌握迭代法。

 

 110.平衡二叉树 (优先掌握递归)

     卡哥建议:再一次涉及到,什么是高度,什么是深度,可以巩固一下。

     题目链接/文章讲解/视频讲解:https://programmercarl.com/0110.%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91.html

     做题思路:

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

     百度上高度定义:二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数(高度从0开始)。

     力扣上高度定义:二叉树节点的高度:指从该节点到叶子节点的节点数(高度从1开始)。我们暂时以leetcode为准(毕竟要在这上面刷题)。

     比较高度,必然是要后序遍历。

     遍历出一个节点的左子树高度和右子树高度后,再比较高度差的绝对值不超过1,如果不超过1,高度就为 1 + max(左子树高度, 右子树高度)。然后代码做了一些改变。

     本题后序遍历的递归法代码:

 1   // 返回以该节点为根节点的二叉树的高度,如果不是平衡二叉树了则返回-1
 2     int getHeight(TreeNode* node) {
 3         if (node == NULL) {
 4             return 0;
 5         }
 6         int leftHeight = getHeight(node->left); //左
 7         if (leftHeight == -1) return -1;
 8         int rightHeight = getHeight(node->right); //右
 9         if (rightHeight == -1) return -1;
10         return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftHeight, rightHeight); //中,返回给根节点的高度
11     }
12     bool isBalanced(TreeNode* root) {
13         return getHeight(root) == -1 ? false : true;
14     }

 

257. 二叉树的所有路径 (优先掌握递归)  

     卡哥建议:这是大家第一次接触到回溯的过程, 我在视频里重点讲解了 本题为什么要有回溯,已经回溯的过程。 如果对回溯 似懂非懂,没关系, 可以先有个印象。 

    题目链接/文章讲解/视频讲解:https://programmercarl.com/0257.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%89%80%E6%9C%89%E8%B7%AF%E5%BE%84.html

     做题思路:

      从根节点一直遍历到左子树的叶子节点,再回溯,从根节点到右子树的叶子节点。所以先使用递归的方式,来做前序遍历。

    看卡哥的是视频和文章吧。

     本题代码:

 1 class Solution {
 2 private:
 3 
 4     void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {
 5         path.push_back(cur->val); // 中,中为什么写在这里,因为最后一个节点也要加入到path中 
 6         // 这才到了叶子节点
 7         if (cur->left == NULL && cur->right == NULL) {
 8             string sPath;
 9             for (int i = 0; i < path.size() - 1; i++) {
10                 sPath += to_string(path[i]);
11                 sPath += "->";
12             }
13             sPath += to_string(path[path.size() - 1]);
14             result.push_back(sPath);
15             return;
16         }
17         if (cur->left) { // 左 
18             traversal(cur->left, path, result);
19             path.pop_back(); // 回溯,每次递归后有一个回溯
20         }
21         if (cur->right) { // 右
22             traversal(cur->right, path, result);
23             path.pop_back(); // 回溯
24         }
25     }
26 
27 public:
28     vector<string> binaryTreePaths(TreeNode* root) {
29         vector<string> result;
30         vector<int> path; //在创建二叉树的时候会有输入,路径也就有了
31         if (root == NULL) return result;
32         traversal(root, path, result);
33         return result;
34     }
35 };

 

 

 404.左叶子之和 (优先掌握递归)

     卡哥建议:其实本题有点文字游戏,搞清楚什么是左叶子,剩下的就是二叉树的基本操作。 

    题目链接/文章讲解/视频讲解:https://programmercarl.com/0404.%E5%B7%A6%E5%8F%B6%E5%AD%90%E4%B9%8B%E5%92%8C.html

    做题思路:

      左叶子的明确定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点。

     判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。

     如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子。判断代码如下:

  if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
    左叶子节点处理逻辑
  }
递归的遍历顺序为后序遍历(左右中),是因为要通过递归函数的返回值来累加求取左叶子数值之和。
当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。

本题代码:
 1  1 int sumOfLeftLeaves(TreeNode* root) {
 2  2         if (root == NULL) return 0;
 3  3         if (root->left == NULL && root->right== NULL) return 0;
 4  4 
 5  5         int leftValue = sumOfLeftLeaves(root->left);    // 左
 6  6         if (root->left && !root->left->left && !root->left->right) { // 左子树就是一个左叶子的情况
 7  7             leftValue = root->left->val;
 8  8         }
 9  9         int rightValue = sumOfLeftLeaves(root->right);  // 右
10 10 
11 11         int sum = leftValue + rightValue;               // 中
12 12         return sum;
13 13     }

 

 

 

标签:随想录,叶子,404,二叉树,path,root,节点,left
From: https://www.cnblogs.com/romantichuaner/p/17625937.html

相关文章

  • 【剑指Offer】58、对称的二叉树
    【剑指Offer】58、对称的二叉树题目描述:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。解题思路:本题判断一棵树是不是对称的,和第18题可以对比分析:二叉树的镜像,和LeetCode第101题:101.对称二叉树是同一道题。解......
  • 【剑指Offer】59、按之字形顺序打印二叉树
    【剑指Offer】59、按之字形顺序打印二叉树题目描述:请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。解题思路:这道题仍然是二叉树的遍历,相当于层次遍历,可以和第22题:从上往下打印二......
  • 剑指 Offer 37. 序列化二叉树(困难)
    题目:classCodec{public:voidrserialize(TreeNode*root,string&str){//编码递归函数:将树按照前序遍历,放入str字符串中。每个节点元素用','分隔if(root==nullptr){//如果遇到空节点,写入"none"。str+="none,";}el......
  • [代码随想录]Day19-二叉树part08
    题目:235.二叉搜索树的最近公共祖先思路:BST和普通二叉树不同的一点是可以根据特性来找最近公共祖先,只要找到第一个值比p大比q小(假设p<q)的节点返回即可。代码:/***Definitionforabinarytreenode.*typeTreeNodestruct{*Valint*Left*TreeNode......
  • 【leetcode】404 左叶子之和
    https://leetcode.cn/problems/sum-of-left-leaves/description/【分析】该题要求左叶子之和。如果我们对当前节点进行叶子节点的判断,那么我们是不知道当前节点是左叶子还是右叶子的。所以我们应该在叶子结点的上层(父节点)进行判断。【代码】classSolution:defsumOfL......
  • 【剑指Offer】38、二叉树的深度
    题目描述:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。解题思路:本题相对比较简单。根据二叉树深度的定义,我们有以下理解:如果一棵树只有一个结点,那么它的深度为1。如果根结点只有左子树而没有右子树,那么......
  • 代码随想录算法训练营第十三天|单调数列:滑动窗口最大值(力扣239.)、优先级队列:前k个高
    单调数列:滑动窗口最大值(力扣239.)给定滑动窗口的范围,求每个滑动窗口范围内的最大值使用单调队列实现对于最大值数字前面的数字不存入数列,对于最大值数字后面的数字存入数列中单调队列中数字的大小呈递减顺序pop(value):如果窗口移除的元素等于单调队列的队口元素,则pop;否则什......
  • 新增@ComponentScan,访问接口404?
    1.起因:自定义一个接口日志注解。打算为所有的接口打印日志和耗时等信息。将定义的@IfLog注解加到HiController的/hi接口因为Application仅扫描和他同一个包下所有类,所以在启动类上增加了@ComponentScan({"com.wxy.log.common"})用于扫描新增的日志切面。访问接......
  • [代码随想录]Day18-二叉树part07
    题目:530.二叉搜索树的最小绝对差思路:一个关键问题——BST的中序遍历是由小到大的顺序,也就是说记录遍历的前一个节点,每次比较当前节点-前一个节点的值即可(因为由小到大所以当前>前一个)代码:/***Definitionforabinarytreenode.*typeTreeNodestruct{*Val......
  • 代码随想录算法训练营第十一天|力扣20.有效的括号、力扣1047.删除字符串中所有相邻重
    有效的括号(力扣20.)括号匹配时使用栈解决的经典问题题意其实就像我们在写代码的过程中,要求括号的顺序是一样的有左括号,那么在对应位置则必须有右括号第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以returnfalse第二种情况:遍历字......