第十八天|513. 找树左下角的值 112. 路径总和 113. 路径总和 II 106. 从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树

二叉树好勾吧难!

513. 找树左下角的值

class Solution {
public:
    int max=0;
    int res;
    void finding(TreeNode* node,int depth){
        if(!node->left&&!node->right&&depth>max){
            max=depth;
            res=node->val ;
        }
        if(node->left)finding(node->left,depth+1);
        if(node->right)finding(node->right,depth+1);
        return ;
    }
    int findBottomLeftValue(TreeNode* root) {
        int depth=0;
        finding(root,depth+1);
        return res;
    }
};

用一个max来限定加上先找左边,那么就可以找到最左的那个值,用一定的规则在递归中寻找自己想要的,就像那个左叶子的和一样。

112. 路径总和

class Solution {
public:
    bool path(TreeNode* node,int sum,int targetSum){
        if(node->left==nullptr&&node->right==nullptr){
            if(sum+node->val==targetSum)return 1;
        }
        bool left=0;
        bool right=0;
        if(node->left)left=path(node->left,sum+(node->val),targetSum);
        if(node->right)right=path(node->right,sum+(node->val),targetSum);
        return (left||right);
    } 
    bool hasPathSum(TreeNode* root, int targetSum) {
        int sum=0;
        if(root==nullptr)return 0;
        return path(root,sum,targetSum);
    }
};

 类似回溯 的做法,寻找记录路径

113. 路径总和Ⅱ

class Solution {
public:
    vector<int> way;
    vector<vector<int>> ways;
    void pathWay(TreeNode* node,int sum){
        way.push_back(node->val);
       if(!node->left&&!node->right&&sum==node->val){
            
            ways.push_back(way);
            return;
        }
        if(node->left){pathWay(node->left,sum-(node->val));way.pop_back();}
        if(node->right){pathWay(node->right,sum-(node->val));way.pop_back();}
        return;
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {

        if(root==nullptr)return ways;
        pathWay(root,targetSum);
        return ways;
    }
};

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

class Solution {
public:
    int rootValue;
    TreeNode* building(vector<int>& inorder, vector<int>& postorder){
        if(postorder.size()==0)return nullptr;
        TreeNode* node= new TreeNode(postorder[postorder.size()-1]);
        if(postorder.size()==1)return node;
        int i;
        for(i=0;i<inorder.size();i++){
            if(inorder[i]==postorder[postorder.size()-1]){
                rootValue=inorder[i];
                break;
            }
        }

        vector<int> leftInorder(inorder.begin(),inorder.begin()+i);
        vector<int> rightInorder(inorder.begin()+i+1,inorder.end());

        
        postorder.resize(postorder.size()-1);
        vector<int> leftPostorder(postorder.begin(),postorder.begin()+i);
        vector<int> rightPostorder(postorder.begin()+i,postorder.end());
        node->left=building(leftInorder,leftPostorder);
        node->right=building(rightInorder,rightPostorder);
        return node;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {

        return building(inorder,postorder);
    }
};

用数组记录耗费空间很大。

105. 从前序与中序遍历序列构造二叉树

class Solution {
public:
    TreeNode* building (vector<int> &preorder,int preorderBegin,int preorderEnd,vector<int> &inorder,int inorderBegin,int inorderEnd){
        if(preorderBegin==preorderEnd)return nullptr;
        TreeNode* node=new TreeNode(preorder[preorderBegin]);
        int i;
        for(i=inorderBegin;i<inorderEnd;i++){
            if(inorder[i]==preorder[preorderBegin]){
                break;
            }
        }
        int inorderLeftEnd=i;
        int inorderRightBegin=i+1;

        preorderBegin+=1;
        int preorderLeftEnd=preorderBegin+i-inorderBegin;
        int preorderRightBegin=preorderLeftEnd;
        node->left=building(preorder, preorderBegin,preorderLeftEnd,inorder,inorderBegin,inorderLeftEnd);
        node->right=building(preorder, preorderRightBegin,preorderEnd,inorder,inorderRightBegin,inorderEnd);
        return node;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return building(preorder,0,preorder.size(),inorder,0,inorder.size());
    }
};

所以这里用两个指针,去指向数组首尾,这里前序或后续的分割要注意,到底左边部分的结尾是多少。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值