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

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

层序迭代法:将遍历最深一层之前队列第一个值取出来就是结果。

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> que;
        que.push(root);
        int result = root->val;
        while(!que.empty()) {
            size_t size = que.size();
            result = que.front()->val;
            while(size--) {
                if(que.front()->left)
                    que.push(que.front()->left);
                if(que.front()->right)
                    que.push(que.front()->right);
                que.pop();
            }
        }
        return result;
    }
};

递归法:

为什么在max_depth更新时取节点的值,最终就是结果?

左右子树遍历顺序决定,先遍历左子树,保证每层在遍历时第一个元素为每层最右侧的值。

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        int max_depth = 1;
        int result = root->val;
        backtracking(root, max_depth, result, 1);
        return result;
    }

    void backtracking(TreeNode* node, int& max_depth, int& result, int depth){
        if(node->right == nullptr && node->left == nullptr){
            if(depth > max_depth) {
                result = node->val;
                max_depth = depth;
            }
        }

        if(node->left) backtracking(node->left, max_depth, result, depth + 1);
        if(node->right) backtracking(node->right, max_depth, result, depth + 1);
    }
};

题目链接:112. 路径总和

自己写的代码没看视频,选用中序遍历,每次第一个取到当前节点的值

class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root == nullptr) return false;
        targetSum = targetSum - root->val;
        if(root->left == nullptr && root->right == nullptr && targetSum == 0) return true;

        bool right = false, left = false;
        if(root->left) left = hasPathSum(root->left, targetSum);
        if(left) return left;
        if(root->right) right = hasPathSum(root->right, targetSum);
        return right;
    }
};

题目链接:113. 路径总和 II

与上题思路相同

class Solution {
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        vector<int> vec;
        vector<vector<int>> result;
        frontReaversal(root, targetSum, vec, result);
        return result;
    }

    void frontReaversal(TreeNode* node, int targetSum, vector<int>& vec, vector<vector<int>>& result) {
        if(node == nullptr) return;
        targetSum -= node->val;
        vec.push_back(node->val);
        if(node->left == nullptr && node->right == nullptr && targetSum == 0){
            result.push_back(vec);
        }
        if(node->left) frontReaversal(node->left, targetSum, vec, result);
        if(node->right) frontReaversal(node->right, targetSum, vec, result);
        vec.pop_back();
    }
};

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

题目前提:数组中元素各不相同。

思路:后续遍历数组取最后一个元素为根节点,找到中序遍历数组中根节点的位置,该位置左右两侧为左右子树各元素,以及元素数量。在后续遍历数组中划分左右子树,递归。

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(postorder.empty()) return nullptr;
        TreeNode* curr = new TreeNode(*(postorder.end() - 1));
        vector<int>::iterator iter;
        iter = inorder.begin();
        while(*iter != curr->val) iter++;
        vector<int> left_tree_inorder(inorder.begin(), iter);
        vector<int> left_tree_postorder(postorder.begin(), postorder.begin() + (iter - inorder.begin()));
        curr->left = buildTree(left_tree_inorder, left_tree_postorder);
        vector<int> right_tree_inorder(iter + 1, inorder.end());
        vector<int> right_tree_postorder(postorder.begin() + (iter - inorder.begin()), postorder.end() - 1);
        curr->right = buildTree(right_tree_inorder, right_tree_postorder);
        return curr;
    }
};

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

思路与上题类似

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.empty()) return nullptr;
        TreeNode* curr = new TreeNode(preorder[0]);
        int mid_idx = 0;
        while(inorder[mid_idx] != curr->val) mid_idx++;
        vector<int> left_preorder(preorder.begin() + 1, preorder.begin() + 1 + mid_idx);
        vector<int> left_inorder(inorder.begin(), inorder.begin() + mid_idx);
        curr->left = buildTree(left_preorder, left_inorder);
        vector<int> right_preorder(preorder.begin() + 1 + mid_idx, preorder.end());
        vector<int> right_inorder(inorder.begin() + mid_idx + 1, inorder.end());
        curr->right = buildTree(right_preorder, right_inorder);
        return curr;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值