小工具知识网

当前位置: 首页 > 行业知识 > @[TOC](代码随想录算法训练营第十八天|Leetcode513 找树左下角的值、Leetcode112 路径总和、Leetcode106 从中序与后序遍历序列构造二叉树

行业知识

@[TOC](代码随想录算法训练营第十八天|Leetcode513 找树左下角的值、Leetcode112 路径总和、Leetcode106 从中序与后序遍历序列构造二叉树

2026-10-30 21:02:57 来源:互联网转载

代码随想录算法训练营第十八天|Leetcode513 找树左下角的值、Leetcode112 路径总和 113 路径总和ii、Leetcode106 从中序与后序遍历序列构造二叉树 105 从前序与中序遍历序列构造二叉树

  • ● Leetcode513 找树左下角的值
    • ● 解题思路
    • ● 代码实现
    • ● Leetcode112 路径总和
      • ● 解题思路
      • ● 代码实现
      • ● 相关题目:Leetcode113 路径总和ii
        • ● 解题思路
        • ● 代码实现
        • ● Leetcode106 从中序与后序遍历序列构造二叉树
          • ● 使用数组元素构建二叉树
          • ● 解题思路
          • ● 代码实现
          • ● 相关题目:Leetcode105 从前序与中序遍历序列构造二叉树
            • ● 代���实现

              ● Leetcode513 找树左下角的值

              题目链接:Leetcode513 找树左下角的值

              视频讲解:代码随想录|找树左下角的值

              题目描述:给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

              假设二叉树中至少有一个节点。

              示例 1:

              输入: root = [2,1,3]

              输出: 1

              示例 2:

              输入: [1,2,3,4,null,5,6,null,null,7]

              输出: 7

              ● 解题思路

              方法一:递归

              (1)确定递归函数的参数和返回值:

              我们定义了result的全局变量存储最终结果,因此在traversal遍历过程直接对其更改即可,不需要其他返回值,因此在traversal返回值为void,同时需要传入递归的结点和递归时传入结点的深度;

              (2)确定递归终止条件:

              我们需要得到的是左下角的值,显然左下角的值不管是上一层结点的左孩子或者右孩子,都一定会是叶子结点,同时我们需要对其深度进行判断,因此左下角的值一定处于二叉树的最后一层,即深度最大;

              (3)确定单层遍历逻辑:

              因为我们需要得到左下角的结点,因此和中结点的处理没有关系,所以无论哪种遍历都可以实现。

              需要再次注意,左下角的值不一定是左结点,当倒数第二层最左侧结点只有右孩子而没有左孩子,此时其右孩子将会是最左结点;同时注意每一次递归都需要对应一次回溯。

              方法二:迭代

              本题使用层序遍历进行迭代解决更简单,我们将最后一层的队头元素返回即可。

              ● 代码实现

              方法一:递归

              /** * 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 maxDepth = INT_MIN;//存储最大深度    int result;    void traversal(TreeNode* node, int depth)    {        //终止条件        if(!node->left && !node->right)        {            if(depth > maxDepth)            {                maxDepth = depth;                result = node->val;            }            return;        }        //左        if(node->left)        {            depth++;            traversal(node->left, depth);//递归            depth--;//回溯        }        //右        if(node->right)        {            depth++;            traversal(node->right, depth);//递归            depth--;//回溯        }        return;    }    int findBottomLeftValue(TreeNode* root) {        traversal(root, 0);        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:    int maxDepth = INT_MIN;    int result;    void traversal(TreeNode* node, int depth)    {        //终止条件        if(!node->left && !node->right)        {            if(depth > maxDepth)            {                maxDepth = depth;                result = node->val;            }            return;        }        //左        if(node->left)        {            traversal(node->left, depth + 1);        }        //右        if(node->right)        {            traversal(node->right, depth + 1);        }    }    int findBottomLeftValue(TreeNode* root) {        traversal(root, 0);        return result;    }};

              这里注意不能depth++,如果自加操作后就改变了depth的值,无法完成回溯操作。

              方法二:迭代

              /** * 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 findBottomLeftValue(TreeNode* root) {        queue que;        int result = 0;        if(!root) return result;        que.push(root);        while(!que.empty())        {            int size = que.size();            result = que.front()->val;            for(int i = 0; i left) que.push(node->left);                if(node->right) que.push(node->right);            }        }        return result;    }};

              ● Leetcode112 路径总和

              题目链接:Leetcode112 路径总和

              视频讲解:代码随想录|路径总和

              题目描述:给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

              叶子节点 是指没有子节点的节点。

              示例 1:

              输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22

              输出:true

              解释:等于目标和的根节点到叶节点路径如上图所示。

              示例 2:

              输入:root = [1,2,3], targetSum = 5

              输出:false

              解释:树中存在两条根节点到叶子节点的路径:

              (1 --> 2): 和为 3

              (1 --> 3): 和为 4

              不存在 sum = 5 的根节点到叶子节点的路径。

              示例 3:

              输入:root = [], targetSum = 0

              输出:false

              解释:由于树是空的,所以不存在根节点到叶子节点的路径。

              ● 解题思路

              方法一:迭代

              (1)确定递归函数参数和返回值:

              我们只需要判断某条路径是否结点值相加总和是否等于target,因此返回值为bool,传入参数为node和target即可;

              (2)确定函数的终止条件:

              在遍历过程中,我们会在某条路径上遇到两种可能,第一种是到叶子结点时,整个路径值相加不等于target,将其返回false;另一种就是等于target,将true的结果返回给上一层告诉该路径有满足条件;

              (3)确定单层遍历逻辑:

              在整个遍历过程中,我们不需要对中进行任何处理,只需要遍历左右结点的路径上是否有满足==target的情况,因此无论使用哪种遍历顺序都是可以的。

              同时,当左右结点有满足:if(traversal(node->left/right, target - node->left/right- >val)),就需要返回true;

              方法二:迭代

              迭代法解决本题主要需要借助栈,但栈中的元素需要使用pari,其中int存储的值为从根结点到该结点路径的总和,思路理解确实不难,但在向栈中压入元素时注意first和second,脑子不乱但手可能乱。

              ● 代码实现

              方法一:迭代

              /** * 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:    bool traversal(TreeNode* node, int targetSum)    {        //终止条件        if(!node->left && !node->right && targetSum == 0) return true;        if(!node->left && !node->right) return false;        //左        if(node->left)        {            targetSum -= node->left->val;            if(traversal(node->left, targetSum)) return true;            targetSum += node->left->val;        }        //右        if(node->right)        {            targetSum -= node->right->val;            if(traversal(node->right, targetSum)) return true;            targetSum += node->right->val;        }        return false;    }    bool hasPathSum(TreeNode* root, int targetSum) {        if(!root) return false;        return traversal(root, targetSum - root->val);    }};

              隐藏回溯细节之后得到:

              /** * 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:    bool traversal(TreeNode* node, int count)    {        //终止条件        if(!node->left && !node->right && count == 0) return true;        if(!node->left && !node->right) return false;        //左        if(node->left && traversal(node->left, count - node->left->val)) return true;        //右        if(node->right && traversal(node->right, count - node->right->val)) return true;        return false;    }    bool hasPathSum(TreeNode* root, int targetSum) {        if(!root) return false;        return traversal(root, targetSum - root->val);    }};

              最终精简为:

              class Solution {public:    bool hasPathSum(TreeNode* root, int sum) {        if (!root) return false;        if (!root->left && !root->right && sum == root->val) {            return true;        }        return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val);    }};

              方法二:迭代

              /** * 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:    bool hasPathSum(TreeNode* root, int targetSum) {        if(!root) return false;        stack st;        st.push(pair(root, root->val));        while(!st.empty())        {            pair node = st.top(); st.pop();            if(!node.first->left && !node.first->right && node.second == targetSum) return true;            if(node.first->right)            {                st.push(pair(node.first->right, node.second + node.first->right->val));            }            if(node.first->left)            {                st.push(pair(node.first->left, node.second + node.first->left->val));            }        }        return false;    }};

              ● 相关题目:Leetcode113 路径总和ii

              题目链接:Leetcode113 路径总和ii

              题目描述:给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

              叶子节点 是指没有子节点的节点。

              示例 1:

              输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22

              输出:[[5,4,11,2],[5,8,4,5]]

              示例 2:

              输入:root = [1,2,3], targetSum = 5

              输出:[]

              示例 3:

              输入:root = [1,2], targetSum = 0

              输出:[]

              ● 解题思路

              本题整体思路和返回true or false相同,但在结果需要返回满足要求的所有路径,我们使用两个vector,一个存储遍历的路径,一个将满足条件的路径保存在result中,最后输出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:    vector result;    vector path;    void traversal(TreeNode* node, int count)    {        //终止条件        if(!node->left && !node->right && count == 0)        {            result.push_back(path);            return;        }        //左        if(node->left)        {            path.push_back(node->left->val);            count -= node->left->val;            traversal(node->left, count);            count += node->left->val;            path.pop_back();        }        //左        if(node->right)        {            path.push_back(node->right->val);            count -= node->right->val;            traversal(node->right, count);            count += node->right->val;            path.pop_back();        }        return;    }    vector pathSum(TreeNode* root, int targetSum) {        result.clear();        path.clear();        if(!root) return result;        path.push_back(root->val);        traversal(root, targetSum - root->val);        return result;    }};

              ● Leetcode106 从中序与后序遍历序列构造二叉树

              题目链接:Leetcode106 从中序与后序遍历序列构造二叉树

              视频讲解:代码随想录|从中序与后序遍历序列构造二叉树

              题目描述:给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

              示例 1:

              输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]

              输出:[3,9,20,null,null,15,7]

              示例 2:

              输入:inorder = [-1], postorder = [-1]

              输出:[-1]

              提示:

              1 public: TreeNode* traversal(vector //·当数组大小为0,返回nullptr if(postorder.size() == 0) return nullptr; //·当数组不为空,后序结果的最后一个值为根结点 int rootValue = postorder[postorder.size() - 1]; TreeNode* root = new TreeNode(rootValue); //·找到后序数组最后一个元素在中序数组的位置,作为切割点 int index; for(index = 0; index

              ● 相关题目:Leetcode105 从前序与中序遍历序列构造二叉树

              题目链接:Leetcode105 从前序与中序遍历序列构造二叉树

              题目描述:给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

              示例 1:

              输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

              输出: [3,9,20,null,null,15,7]

              示例 2:

              输入: preorder = [-1], inorder = [-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:    TreeNode* traversal(vector& preorder, int preorderBegin, int preorderEnd, vector& inorder, int inorderBegin, int inorderEnd)    {        if(preorderBegin == preorderEnd) return nullptr;        int rootValue = preorder[preorderBegin];        TreeNode* root = new TreeNode(rootValue);        if(preorderEnd - preorderBegin == 1) return root;        int index;        for(index = 0; index left = traversal(preorder, leftpreorderBegin, leftpreorderEnd ,inorder, leftinorderBegin, leftinorderEnd);        root->right = traversal(preorder, rightpreorderBegin, rightpreorderEnd, inorder, rightinorderBegin, rightinorderEnd);        return root;    }    TreeNode* buildTree(vector& preorder, vector& inorder) {        if(preorder.size() == 0 || inorder.size() == 0) return nullptr;        return traversal(preorder, 0, preorder.size(), inorder, 0, inorder.size());    }};

上一篇:戴尔服务器怎么装普通系统?

下一篇:抖音相册下载攻略,轻松掌握下载方法!