代码随想录第18天,LeetCode513找树左下角的值;112路径之和;113路径之和II;106从中许与后序遍历序列构造二叉树105从中许与前序遍历序列构造二叉树

文章介绍了四个关于二叉树的C++解决方案,涉及深度优先搜索、路径和值查找,以及使用中序遍历和后序遍历来构建二叉树的方法。
摘要由CSDN通过智能技术生成

题目:513
class Solution {
public:
int maxDepth=INT_MIN;
int result;
void travselval(TreeNode* root,int depth){
if(root->leftNULL&&root->rightNULL){
if(depth>maxDepth){
maxDepth=depth;
result=root->val;
}
}
if(root->left){
depth++;
travselval(root->left,depth);
depth–;
}
if(root->right){
depth++;
travselval(root->right,depth);
depth–;
}
return;
}
int findBottomLeftValue(TreeNode* root) {
travselval(root,0);
return result;

}

};
题目:112
class Solution {
private:
bool travsel(TreeNode cur,int count){
if(!cur->left && !cur->right && count ==0) return true;
if(!cur->left && !cur->right) return false;
if(cur->left){
count-=cur->left->val;
if(travsel(cur->left,count)) return true;
count+=cur->left->val;
}
if (cur->right) { // 右
count -= cur->right->val; // 递归,处理节点;
if (travsel(cur->right, count)) return true;
count += cur->right->val; // 回溯,撤销处理结果
}
return false;
}
public:
bool hasPathSum(TreeNode
root, int targetSum) {
if(root==NULL ) return false;
return travsel(root,targetSum-root->val);

}

};
题目:113路径之和II
class Solution {
private:
vector<vector>result;
vector path;
void traversal(TreeNode cur, int count){
if(cur->leftNULL&&cur->rightNULL && count0) {
result.push_back(path);
return;
}
if(cur->left
NULL&& cur->right==NULL) return;
if(cur->left){
path.push_back(cur->left->val);
count-=cur->left->val;
traversal(cur->left,count);
count+=cur->left->val;
path.pop_back();
}
if(cur->right){
path.push_back(cur->right->val);
count-=cur->right->val;
traversal(cur->right,count);
count+=cur->right->val;
path.pop_back();
}
return;
}
public:
vector<vector> pathSum(TreeNode
root, int targetSum) {
result.clear();
path.clear();
if(root==NULL) return result;
path.push_back(root->val);
traversal(root,targetSum-root->val);
return result;

}

};
题目:106
private:
TreeNode* traversal (vector& inorder, vector& postorder) {
if (postorder.size() == 0) return NULL;

    // 后序遍历数组最后一个元素,就是当前的中间节点
    int rootValue = postorder[postorder.size() - 1];
    TreeNode* root = new TreeNode(rootValue);

    // 叶子节点
    if (postorder.size() == 1) return root;

    // 找到中序遍历的切割点
    int delimiterIndex;
    for (delimiterIndex = 0; delimiterIndex < inorder.size(); delimiterIndex++) {
        if (inorder[delimiterIndex] == rootValue) break;
    }

    // 切割中序数组
    // 左闭右开区间:[0, delimiterIndex)
    vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex);
    // [delimiterIndex + 1, end)
    vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end() );

    // postorder 舍弃末尾元素
    postorder.resize(postorder.size() - 1);

    // 切割后序数组
    // 依然左闭右开,注意这里使用了左中序数组大小作为切割点
    // [0, leftInorder.size)
    vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());
    // [leftInorder.size(), end)
    vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());

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

    return root;
}

public:
TreeNode* buildTree(vector& inorder, vector& postorder) {
if (inorder.size() == 0 || postorder.size() == 0) return NULL;
return traversal(inorder, postorder);
}
};
题目:105
class Solution {
private:
TreeNode* traversal (vector& inorder, int inorderBegin, int inorderEnd, vector& preorder, int preorderBegin, int preorderEnd) {
if (preorderBegin == preorderEnd) return NULL;

    int rootValue = preorder[preorderBegin]; // 注意用preorderBegin 不要用0
    TreeNode* root = new TreeNode(rootValue);

    if (preorderEnd - preorderBegin == 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;

    // 切割前序数组
    // 前序左区间,左闭右开[leftPreorderBegin, leftPreorderEnd)
    int leftPreorderBegin =  preorderBegin + 1;
    int leftPreorderEnd = preorderBegin + 1 + delimiterIndex - inorderBegin; // 终止位置是起始位置加上中序左区间的大小size
    // 前序右区间, 左闭右开[rightPreorderBegin, rightPreorderEnd)
    int rightPreorderBegin = preorderBegin + 1 + (delimiterIndex - inorderBegin);
    int rightPreorderEnd = preorderEnd;

    root->left = traversal(inorder, leftInorderBegin, leftInorderEnd,  preorder, leftPreorderBegin, leftPreorderEnd);
    root->right = traversal(inorder, rightInorderBegin, rightInorderEnd, preorder, rightPreorderBegin, rightPreorderEnd);

    return root;
}

public:
TreeNode* buildTree(vector& preorder, vector& inorder) {
if (inorder.size() == 0 || preorder.size() == 0) return NULL;

    // 参数坚持左闭右开的原则
    return traversal(inorder, 0, inorder.size(), preorder, 0, preorder.size());
}

};

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值