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

第18天。


前言

今日文案:

哀愁的人,给他们安慰,饥饿的人,给他们食物,而我所能做的,为什么总只是后者。

                                                                                                                      ——三毛《温柔的夜》


一、找树左下角的值

力扣

class Solution {
public:

    int maxdepth=-1;
    int res=0;

    void traversal(TreeNode*root,int depth)
    {
        if(root->left==NULL&&root->right==NULL)        //叶子节点是返回条件
        {
            if(depth>maxdepth)                    //找出深度最大的,保持值就行
            {
                maxdepth=depth;
                res=root->val;
            }
            return ;
        }
        if(root->left)                //遍历所有节点,优先左节点
        {
            depth++;
            traversal(root->left,depth);
            depth--;                        //回溯
        }
        if(root->right)
        {
            depth++;
            traversal(root->right,depth);
            depth--;
        }
    }

    int findBottomLeftValue(TreeNode* root) {
        traversal(root,0);
        return res;
    }
};

二、路径总和

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

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

力扣

解题思路:

关键是使用回溯,在遍历所有数组的时候,记得要设置回溯。

class Solution {
public:

    int sum=0;
    bool traversal(TreeNode*root,int tarfetSum)
    {
        if(root->right==0&&root->left==0)        叶子节点
        {
            if(sum==tarfetSum)                //判断
            return true;
            else
            return false;
        }
        if(root->left)
        {
            sum+=root->left->val;
            if(traversal(root->left,tarfetSum))
            {
                return true;
            }
           sum-=root->left->val;                //回溯
        }
        if(root->right)
        {
            sum+=root->right->val;
            if(traversal(root->right,tarfetSum))
            {
                return true;
            }
            sum-=root->right->val;
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==0)
        return  false;
        else
        sum+=root->val;
        return traversal(root,targetSum);
    }
};

三、路径总和||

力扣

解题思路:

和层序遍历差不多,主要是回溯的问题。

class Solution {
public:

    int sum=0;
    vector<int> path;
    vector<vector<int>> ans;
    void traversal(TreeNode*root,int targetSum)
    {
        if(root->left==NULL&&root->right==NULL)
        {
            if(sum==targetSum)                    //判断条件
            {
                ans.push_back(path);            //储存
                return;
            }
            else
                return;
        }
        if(root->left)
        {
            path.push_back(root->left->val);
            sum+=root->left->val;
            traversal(root->left,targetSum);
            path.pop_back();                        //回溯
            sum-=root->left->val;                //回溯
        }
        if(root->right)
        {
            path.push_back(root->right->val);
            sum+=root->right->val;
            traversal(root->right,targetSum);
            path.pop_back();
            sum-=root->right->val;
        }
    }

    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if(root==0)
        return ans;
        else
        {
            path.push_back(root->val);
            sum+=root->val;
            traversal(root,targetSum);
        }
        return ans;
    }
};

四、从中序与后序遍历序列构造二叉树

力扣

解题思路:

本题的核心在于切割数组,中序和后序的顺序是,左中右左右中,那么我们可以很简单地从后序数组中找出我们的中节点,我们取它的值去遍历中序数组,找到中节点,中节点左边就是左子树,右边就是右子树,这样我们又可以折射回后序数组,如此反复,完成构建,具体代码以及解析如下。

class Solution {
public:

    TreeNode*traversal(vector<int>& inorder, vector<int>& postorder)
    {
        if(postorder.size()==0)          //如果后序数组为0,那就等于没有中节点了,返空吧
        {
            return NULL;
        }
        int rootVal=postorder[postorder.size()-1];    //记录后序数组最后一个值
        int i=0;                                    //后面要记录下标
        for(i=0;i<inorder.size();i++)            //遍历
        {
            if(rootVal==inorder[i])
            {
                break;                    //找到了直接出
            }
        }

        TreeNode*root=new TreeNode(rootVal);    //创建新节点
         if (postorder.size() == 1) return root;
        postorder.resize(postorder.size()-1);                //后序数组去掉末尾
        vector<int> leftinorder(inorder.begin(),inorder.begin()+i);    //中序左子树
        vector<int> rightinorder(inorder.begin()+i+1,inorder.end());    //中序右子树
                                                //记得此处加1,因为是左开右闭且跳过中
        vector<int> leftpostorder(postorder.begin(),postorder.begin()+leftinorder.size()); //后序左子树
        vector<int> righpostorde(postorder.begin()+leftinorder.size(),postorder.end());

        root->left=traversal(leftinorder,leftpostorder);
        root->right=traversal(rightinorder,righpostorde);
        return root;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
       return traversal( inorder, postorder);
    }
};


总结

分清楚前中后序的处理逻辑

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值