代码随想录算法训练营第十六天|​LeetCode513. 找树左下角的值​、LeetCode112 113. 路径总和 路径总和Ⅱ、LeetCode106. 从中序与后序遍历序列构造二叉树

目录

前言

一、LeetCode513. 找树左下角的值​

题目链接:

题目思路:

代码:

二、LeetCode112 113. 路径总和 路径总和Ⅱ

题目链接:

代码思路:

代码:

路径总和:

路径总和Ⅱ:

三、LeetCode106. 从中序与后序遍历序列构造二叉树

题目链接:

题目思路:

代码:


前言

​LeetCode513. 找树左下角的值​

视频讲解:LeetCode:513.找二叉树左下角的值_哔哩哔哩_bilibili

文章讲解:代码随想录

LeetCode112 113. 路径总和 路径总和Ⅱ

视频讲解:LeetCode:112. 路径总和_哔哩哔哩_bilibili

文章讲解:代码随想录

LeetCode106. 从中序与后序遍历序列构造二叉树

视频讲解:LeetCode:106.从中序与后序遍历序列构造二叉树_哔哩哔哩_bilibili

文章讲解:代码随想录


一、LeetCode513. 找树左下角的值​

题目链接:

513. 找树左下角的值 - 力扣(LeetCode)

题目思路:

找树的左下角的值要注意的是,这个只有可能是一个结点的左孩子结点,也可能是右孩子结点,例如下图中我们要找的就是结点2左孩子结点的值

而下图则是要找到结点2右孩子的结点值

前中后序遍历都会先遍历左结点然后才会遍历右结点,所以通过遍历并判断结点的深度,我们可以优先找到最深一层结点的最左结点。

代码:

/**
 * 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 {
private:
    int maxDepth = INT32_MIN;
    int result;
    void backTrace(TreeNode* root, int depth) {
        if (root->left == nullptr && root->right == nullptr) {
            if (depth > maxDepth)
            {
                maxDepth = depth;
                result = root->val;
            }
        }
        if(root->left)
        {
            depth++;
            backTrace(root->left, depth);;
            depth--;
        }
        if(root->right)
        {
            depth++;
            backTrace(root->right, depth);
            depth--;
        }
    }
public:
    int findBottomLeftValue(TreeNode* root) {
        maxDepth = INT32_MIN;
        backTrace(root, 0);
        return this->result;
    }
};

二、LeetCode112 113. 路径总和 路径总和Ⅱ

题目链接:

112. 路径总和 - 力扣(LeetCode)

113. 路径总和 II - 力扣(LeetCode)

代码思路:

通过递归遍历,一直记录当前的结点值之和(此处的count通过减去遍历的结点值来“反向”记录结点值之和)。当遍历到叶子结点,我们可以判断count是否为0,如果为0则代表这条路径的结点之和为目标值,则代表这条路径符合要求。

代码:

路径总和:

/**
 * 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* root, int count)
    {
        if(root->left == nullptr && root->right == nullptr)
        {
            if(count == 0)
                return true;
            else
                return false;
        }
        if(root->left)
        {
            count -= root->left->val;
            if(traversal(root->left, count))
                return true;
            count += root->left->val;
        }
        if(root->right)
        {
            count -= root->right->val;
            if(traversal(root->right, count))
                return true;
            count += root->right->val;
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root == nullptr) return 0;

        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:
    vector<vector<int>> result;
    void traversal(TreeNode* root, vector<int> path, int count)
    {
        path.push_back(root->val);
        if(root->left == nullptr && root->right == nullptr && count == 0)
        {
            this->result.push_back(path);
            return ;
        }
        if(root->left)
        {
            traversal(root->left, path, count - root->left->val);
        }
        if(root->right)
        {
            traversal(root->right, path, count - root->right->val);
        }
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if(root == nullptr) return {};
        this->result.clear();
        vector<int> path;
        traversal(root, path, targetSum - root->val);
        return this->result;
    }
};

三、LeetCode106. 从中序与后序遍历序列构造二叉树

题目链接:

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

题目思路:

首先我们要知道通过中序和后序手动得到二叉树结构的步骤,后序序列用来判断根结点的位置,中序序列通过后序序列得到的根节点,对左右子树进行划分,然后再通过后序序列对左右子树找根节点,再不断的对左右子树进行划分。

代码步骤: 

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

代码:

/**
 * 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* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(postorder.size() == 0)
            return NULL;
        
        int rootVal = postorder[postorder.size() - 1];
        TreeNode* root = new TreeNode(rootVal);
        if(postorder.size() == 1)
            return root;
        
        int index = 0;
        for(index = 0; index < inorder.size(); index++)
        {
            if(inorder[index] == rootVal)
                break;
        }

        // 切割中序数组
        vector<int> leftInorder(inorder.begin(), inorder.begin() + index);
        vector<int> rightInorder(inorder.begin() + index + 1, inorder.end());

        postorder.resize(postorder.size() - 1);

        vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
        vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());

        // // 以下为日志
        // cout << "----------" << endl;

        // cout << "leftInorder :";
        // for (int i : leftInorder) {
        //     cout << i << " ";
        // }
        // cout << endl;

        // cout << "rightInorder :";
        // for (int i : rightInorder) {
        //     cout << i << " ";
        // }
        // cout << endl;

        // cout << "leftPostorder :";
        // for (int i : leftPostorder) {
        //     cout << i << " ";
        // }
        // cout << endl;
        //  cout << "rightPostorder :";
        // for (int i : rightPostorder) {
        //     cout << i << " ";
        // }
        // cout << endl;

        root->left = buildTree(leftInorder, leftPostorder);
        root->right = buildTree(rightInorder, rightPostorder);

        return root;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值