代码随想录算法训练营Day18

Day18 二叉树找树左下角的值、路径总和、从中序与后序遍历序列构造二叉树

力扣相关例题

513. 找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。

示例 :
在这里插入图片描述
输入: root = [2,1,3]
输出: 1

class Solution {
public:
    int result;  // 全局变量 最大深度最左节点的数值
    int maxdepth = INT_MIN; // 全局变量 记录最大深度
    void traveltree(TreeNode* node, int depth) {
        if (node->left == NULL && node->right == NULL) {
            if (depth > maxdepth) {
                maxdepth = depth;
                result = node->val;
            }
            return ;
        }
        //这边一定是先左后右,因为是找左下角的值
        if (node->left != NULL) {
            depth++;
            traveltree(node->left, depth);
            depth--;
        }
        if (node->right != NULL) {
            depth++;
            traveltree(node->right,depth);
            depth--;
        }
        return ;
    }
    int findBottomLeftValue(TreeNode* root) {
        traveltree(root, 0);
        return result;
    }
};

112. 路径总和

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

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

示例 :
在这里插入图片描述
输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。

class Solution {
public:
    bool traveltree(TreeNode* root, int sum) {
        // 叶子结点 且 路径和 等于 目标值
        if (root->left == NULL && root->right == NULL && sum == 0) {
            return true;
        }
        // 叶子结点 且 路径和 不等于 目标值
        if (root->left == NULL && root->right == NULL) {
            return false;
        }
        // 左子树遍历
        if (root -> left) {
            sum -= root->left->val;
            if (traveltree(root->left, sum)) {
                return true;
            }
            sum += root->left->val;  //回溯
        }
        // 右子树遍历
        if (root -> right) {
            sum -= root->right->val;
            if (traveltree(root->right, sum)) {
                return true;
            }
            sum += root->right->val;  //回溯
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        // 这道题是在递归之前就减去当前要递归结点的值,所以才判断是否等于0
        if (root == NULL) {
            return false;
        }
        return traveltree(root, targetSum - root->val); 
    }
};

106. 从中序与后序遍历序列构造二叉树(重点)

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

示例 1:
在这里插入图片描述
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

解题步骤:

  1. 如果数组大小为零的话,说明是空节点了。
  2. 如果不为空,那么取后序数组最后一个元素作为节点元素。
  3. 找到后序数组最后一个元素在中序数组的位置,作为切割点
  4. 切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
  5. 切割后序数组,切成后序左数组和后序右数组
  6. 递归处理左区间和右区间
class Solution {
public:
    TreeNode* traveltree(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;
        for (index = 0; index < inorder.size(); index++) {
            if (inorder[index] == rootval) {
                break;
            }
        }
        // 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)(左闭右开)
            //[0, index)   [index+1, end)
        vector<int> leftinorder(inorder.begin(), inorder.begin() + index);
        vector<int> rightinorder(inorder.begin() + index + 1, inorder.end());
        // 第五步:切割后序数组,切成后序左数组和后序右数组(左闭右开)
        postorder.resize(postorder.size() - 1);  //舍弃末尾结点元素!
            //[0, leftinorder.size)  [leftinorder, end)
        vector<int> leftpostorder(postorder.begin(), postorder.begin() + leftinorder.size());
        vector<int> rightpostorder(postorder.begin() + leftinorder.size(), postorder.end());
        // 第六步:递归处理左区间和右区间
        root->left = traveltree(leftinorder, leftpostorder);
        root->right = traveltree(rightinorder, rightpostorder);

        return root;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if (inorder.size() == 0 || postorder.size() == 0) {
            return NULL;
        }
        return traveltree(inorder, postorder);
    } 
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值