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

1. 题目:给定一个二叉树,在树的最后一行找到最左边的值。

## 层序遍历

class Solution {

public:

    int findBottomLeftValue(TreeNode* root) {

        queue<TreeNode*> que;

        if (root != NULL) que.push(root);

        int result = 0;

        while(!que.empty()){

            int size = que.size();

            for (int i = 0; i < size; i++){

                TreeNode* node = que.front();

                que.pop();

                if (i == 0) result = node -> val;

                if (node -> left) que.push(node -> left);

                if (node -> right) que.push(node -> right);

            }

        }

        return result;

    }

};

## 递归

class Solution {

public:

    int maxDepth = INT_MIN;

    int result;

    void traversal(TreeNode* root, int depth) {

        if (root->left == NULL && root->right == NULL) {

            if (depth > maxDepth) {

                maxDepth = depth;

                result = root->val;

            }

            return;

        }

        if (root->left) {

            depth++;

            traversal(root->left, depth);

            depth--; // 回溯

        }

        if (root->right) {

            depth++;

            traversal(root->right, depth);

            depth--; // 回溯

        }

        return;

    }

    int findBottomLeftValue(TreeNode* root) {

        traversal(root, 0);

        return result;

    }

};

2. 题目:

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

class Solution {
private:
    bool traversal(TreeNode* cur, int count) {
        if (!cur->left && !cur->right && count == 0) return true; // 遇到叶子节点,并且计数为0
        if (!cur->left && !cur->right) return false; // 遇到叶子节点直接返回

        if (cur->left) { // 左
            count -= cur->left->val; // 递归,处理节点;
            if (traversal(cur->left, count)) return true;
            count += cur->left->val; // 回溯,撤销处理结果
        }
        if (cur->right) { // 右
            count -= cur->right->val; // 递归,处理节点;
            if (traversal(cur->right, count)) return true;
            count += cur->right->val; // 回溯,撤销处理结果
        }
        return false;
    }

public:
    bool hasPathSum(TreeNode* root, int sum) {
        if (root == NULL) return false;
        return traversal(root, sum - root->val);
    }
};

3. 题目:

根据一棵树的中序遍历与后序遍历构造二叉树。

注意: 你可以假设树中没有重复的元素。

例如,给出

  • 中序遍历 inorder = [9,3,15,20,7]
  • 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树:

class Solution {

private:

    // 中序区间:[inorderBegin, inorderEnd),后序区间[postorderBegin, postorderEnd)

    TreeNode* traversal (vector<int>& inorder, int inorderBegin, int inorderEnd, vector<int>& postorder, int postorderBegin, int postorderEnd) {

        if (postorderBegin == postorderEnd) return NULL;

        int rootValue = postorder[postorderEnd - 1];

        TreeNode* root = new TreeNode(rootValue);

        if (postorderEnd - postorderBegin == 1) return root;

        int delimiterIndex;

        for (delimiterIndex = inorderBegin; delimiterIndex < inorderEnd; delimiterIndex++) {

            if (inorder[delimiterIndex] == rootValue) break;

        }

        // 切割中序数组

        // 左中序区间,左闭右开[leftInorderBegin, leftInorderEnd)

        int leftInorderBegin = inorderBegin;

        int leftInorderEnd = delimiterIndex;

        // 右中序区间,左闭右开[rightInorderBegin, rightInorderEnd)

        int rightInorderBegin = delimiterIndex + 1;

        int rightInorderEnd = inorderEnd;

        // 切割后序数组

        // 左后序区间,左闭右开[leftPostorderBegin, leftPostorderEnd)

        int leftPostorderBegin =  postorderBegin;

        int leftPostorderEnd = postorderBegin + delimiterIndex - inorderBegin; // 终止位置是 需要加上 中序区间的大小size

        // 右后序区间,左闭右开[rightPostorderBegin, rightPostorderEnd)

        int rightPostorderBegin = postorderBegin + (delimiterIndex - inorderBegin);

        int rightPostorderEnd = postorderEnd - 1; // 排除最后一个元素,已经作为节点了

        root->left = traversal(inorder, leftInorderBegin, leftInorderEnd,  postorder, leftPostorderBegin, leftPostorderEnd);

        root->right = traversal(inorder, rightInorderBegin, rightInorderEnd, postorder, rightPostorderBegin, rightPostorderEnd);

        return root;

    }

public:

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {

        if (inorder.size() == 0 || postorder.size() == 0) return NULL;

        // 左闭右开的原则

        return traversal(inorder, 0, inorder.size(), postorder, 0, postorder.size());

    }

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值