首页 > 编程语言 >「代码随想录算法训练营」第十三天 | 二叉树 part3

「代码随想录算法训练营」第十三天 | 二叉树 part3

时间:2024-07-17 16:55:38浏览次数:13  
标签:node right TreeNode int nullptr 随想录 二叉树 第十三天 left

110. 平衡二叉树

题目链接:https://leetcode.cn/problems/balanced-binary-tree/
题目难度:简单
文章讲解:https://programmercarl.com/0110.平衡二叉树.html
视频讲解:https://www.bilibili.com/video/BV1Ug411S7my
题目状态:通过

思路:

采用递归的方式,遍历每个节点的左右孩子的深度以及其之间的深度差是否超过 1,如果超过 1 的话,就直接返回false,直到遍历结束。

代码实现:

/**
 * 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 isBalancedUtil(TreeNode *root, int &balanced) {
        if(root == nullptr) return 0;
        int leftHeight = isBalancedUtil(root->left, balanced);
        if(balanced == 0) return 0;
        int rightHeight = isBalancedUtil(root->right, balanced);
        if(balanced == 0) return 0;
        if(abs(leftHeight - rightHeight) > 1) balanced = 0;
        return max(leftHeight, rightHeight) + 1;
    }
    bool isBalanced(TreeNode* root) {
        int balanced = 1;
        isBalancedUtil(root, balanced);
        return balanced;
    }
};

代码随想录提供了一种更好的代码:

class Solution {
public:
    int getHeight(TreeNode *node) {
        if(node == nullptr) return 0;
        int leftHeight = getHeight(node->left);
        if(leftHeight == -1) return -1;
        int rightHeight = getHeight(node->right);
        if(rightHeight == -1) return -1;
        return abs(leftHeight - rightHeight) > 1 ? -1 : (max(leftHeight, rightHeight) + 1);
    }
    bool isBalanced(TreeNode *root) {
        return getHeight(root) == -1 ? false : true;
    }
};

257. 二叉树的所有路径

题目链接:https://leetcode.cn/problems/binary-tree-paths/
题目难度:简单
文章讲解:https://programmercarl.com/0257.二叉树的所有路径.html
视频讲解:https://www.bilibili.com/video/BV1ZG411G7Dh
题目状态:一点思路也没有

学习思路:

学习回溯,看下图

回溯和递归是不分开的,当每次进行递归的时候将之前保存的路径中的节点pop出去,这就是回溯。

定义递归函数:

  1. 传入参数:
    a. TreeNode *node:传入一个节点。
    b. vector<int> path:通过一个path来记录沿途的路径,便于之后的回溯。
    c. vector<string> res:用来记录最终结果。
  2. 返回值:没有返回值,递归的结果在res中存放。
  3. 终止条件:当该节点的左孩子和右孩子都为nullptr时,递归终止。
  4. 递归思路:采用前序遍历,先将节点压入path中,再判断其左右孩子是否都为nullptr(此时为递归结束,即该节点为叶子节点),若不为nullptr,分别将其左右孩子(不为空的那个)进入递归,此时将path中该节点pop出来(这个就是回溯)。

代码实现:

/**
 * 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 backtracking(TreeNode *node, vector<int> &path, vector<string> &res) {
        // 中
        path.push_back(node->val);
        // 终止条件
        if(node->left == nullptr && node->right == nullptr) {
            string sPath;
            for(int i = 0; i < path.size() - 1; ++i) {
                sPath += to_string(path[i]);
                sPath += "->";
            }
            sPath += to_string(path[path.size() - 1]);
            res.push_back(sPath);
            return;
        }
        // 左
        if(node->left) {
            backtracking(node->left, path, res);
            path.pop_back();
        }
        // 右
        if(node->right) {
            backtracking(node->right, path, res);
            path.pop_back();
        }
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> res;
        vector<int> path;
        if(root == nullptr) return res;
        backtracking(root, path, res);
        return res;
    }
};

404. 左叶子之和

题目链接:https://leetcode.cn/problems/sum-of-left-leaves/
题目难度:简单
文章讲解:https://programmercarl.com/0404.左叶子之和.html
视频讲解:https://www.bilibili.com/video/BV1GY4y1K7z8
题目状态:通过

个人思路:

定义一个int类型变量leftSum,用来存储结果使用层序遍历,当遍历到该节点的左孩子时,若其左孩子没有左孩子和右孩子(即该节点的左孩子为叶子节点),将其值加入leftSum中。

代码实现:

/**
 * 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 sumOfLeftLeaves(TreeNode* root) {
        queue<TreeNode *> que;
        if(root == nullptr) return 0;
        int leftSum = 0;
        que.push(root);
        while(!que.empty()) {
            TreeNode *node = que.front();
            que.pop();
            if(node->left) {
                que.push(node->left);
                if(node->left->left == nullptr && node->left->right == nullptr) leftSum += node->left->val;
            }
            if(node->right) que.push(node->right);
        }
        return leftSum;
    }
};

递归思想的代码:

/**
 * 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 sumOfLeftLeaves(TreeNode* root) {
        if(root == nullptr) return 0;
        if(root->left == nullptr && root->right == nullptr) return 0;
        int leftValue = sumOfLeftLeaves(root->left);
        if(root->left && !root->left->left && !root->left->right) leftValue += root->left->val;
        int rightValue = sumOfLeftLeaves(root->right);
        // 这里面leftValue代表左孩子的左叶子节点值之和,rightValue代表右孩子的左叶子节点值之和
        int sum = leftValue + rightValue;
        return sum;
    }
};

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

题目链接:https://leetcode.cn/problems/count-complete-tree-nodes/
题目难度:简单
文章讲解:https://programmercarl.com/0222.完全二叉树的节点个数.html
视频讲解:https://www.bilibili.com/video/BV1eW4y1B7pD
题目状态:通过

思路:

层序遍历,加个计数sum

代码实现:

/**
 * 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 countNodes(TreeNode* root) {
        queue<TreeNode *> que;
        if(root == nullptr) return 0;
        que.push(root);
        int sum = 1;
        while(!que.empty()) {
            TreeNode *node = que.front();
            que.pop();
            if(node->left) {
                que.push(node->left);
                sum++;
            }
            if(node->right) {
                que.push(node->right);
                sum++;
            }
        }
        return sum;
    }
};

标签:node,right,TreeNode,int,nullptr,随想录,二叉树,第十三天,left
From: https://www.cnblogs.com/frontpen/p/18307783

相关文章

  • Day 15 二叉树part03
    110.平衡二叉树classSolution{publicbooleanisBalanced(TreeNoderoot){if(root==null)returntrue;returnisBalanced(root.left)&&isBalanced(root.right)&&Math.abs(hight(root.left)-hight(root.right))......
  • 代码随想录算法训练营第14天 | 复习二叉树翻转
    2024年7月17日递归法翻转二叉树易错:要考虑节点为空的情况,以及写好边界条件。/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*TreeNode(intval){this.va......
  • 二叉树 部分定义与性质
    针对于知识回顾/复习,发现一些博客对于一些名词的定义各不相同,于是自己对于部分容易混淆的定义作一个简单的记录。详细关于二叉树的内容可以看:二叉树-Hello算法,部分博客内容来自其中。名词定义1.层层(Level):二叉树中的所有节点可以根据与根节点的距离分成不同的层次。根节点位......
  • 代码随想录算法训练营第26天 | 回溯02:39. 组合总和、40.组合总和II、131.分割回文串
    代码随想录算法训练营第26天|回溯02:39.组合总和、40.组合总和II、131.分割回文串组合总和https://leetcode.cn/problems/combination-sum/代码随想录https://programmercarl.com/0039.组合总和.html40.组合总和IIhttps://leetcode.cn/problems/combination-sum-ii/desc......
  • 代码随想录算法训练营第24天 |
    代码随想录算法训练营第24天|回溯基础理论、第77题.组合、216.组合总和III、回溯基础理论代码随想录https://programmercarl.com/回溯算法理论基础.html#题目分类第77题.组合https://leetcode.cn/problems/combinations/description/代码随想录https://programmercarl.c......
  • 代码随想录之哈希表
    1、有效的字母异位词给定两个字符串s和t,编写一个函数来判断t是否是s的字母异位词。注意:若s和t中每个字符出现的次数都相同,则称s和t互为字母异位词。示例1:输入:s="anagram",t="nagaram"输出:true示例2:输入:s="rat",t="car"输出:......
  • LeetCode第257题:二叉树的所有路径的Java实现
    摘要LeetCode第257题要求生成二叉树的所有从根节点到叶子节点的路径。本文将介绍两种Java解决方案:迭代法和递归法。1.问题描述给定一个二叉树的根节点,按照从根到叶的顺序遍历所有路径,并将它们作为列表的列表返回。2.示例分析输入:[1,2,3,null,null,4]'输出:[[1,2],[1,......
  • 代码随想录刷题Day 14 二叉树part02
    226.翻转二叉树//这道题其实就是遍历二叉树,然后交换每个节点的左右子节点即可。这里我就使用了一个栈来存储需要遍历的节点,每次循环弹出一个,然后交换其左右子节点就好了classSolution{publicTreeNodeinvertTree(TreeNoderoot){Stack<TreeNode>stack=new......
  • 【Java--数据结构】二叉树
    欢迎关注个人主页:逸狼创造不易,可以点点赞吗~如有错误,欢迎指出~树结构树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合注意:树形结构中,子树之间不能有交集,否则就不是树形结构常见概念  节点的度:一个节点含有子树的个数,如A的度为6......
  • 代码随想录day27 递增子序列 | 全排列 | 全排列 II
    递增子序列递增子序列解题思路用set来去重,之后每次一个节点存入时与前一个节点进行大小比较,如果小就不存了,跳过剩余的回溯过程知识点回溯,去重心得在考虑去重的时候忘记了使用C++的数据结构set,得记下这个方法全排列全排列解题思路在回溯迭代的时候传入了一个统计数组元......