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

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

前言


今日文案:

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

                                                                                      ——三毛《温柔的夜》

一、找树左下角的值


力扣

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天前
|
人工智能 测试技术 Windows
【深度优先搜索】【树】【状态压缩】2791. 树中可以形成回文的路径数
【深度优先搜索】【树】【状态压缩】2791. 树中可以形成回文的路径数
|
3天前
二叉树查找值为x的结点、树的高度、第k层结点个数的代码实现
二叉树查找值为x的结点、树的高度、第k层结点个数的代码实现
|
7月前
代码随想录Day15 二叉树 LeetCodeT513 找树左下角的值 T112路径总和 T106 从中序和后序遍历构造二叉树
代码随想录Day15 二叉树 LeetCodeT513 找树左下角的值 T112路径总和 T106 从中序和后序遍历构造二叉树
26 0
|
3天前
|
算法
二叉树的结点个数、叶子结点个数的代码实现<分治算法>
二叉树的结点个数、叶子结点个数的代码实现<分治算法>
|
5月前
|
算法 测试技术 C#
C++深度优先搜索(DFS)算法的应用:树中可以形成回文的路径数
C++深度优先搜索(DFS)算法的应用:树中可以形成回文的路径数
|
6月前
|
算法
代码随想录算法训练营第十八天 | 力扣 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树、105. 从前序与中序遍历序列构造二叉树
代码随想录算法训练营第十八天 | 力扣 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树、105. 从前序与中序遍历序列构造二叉树
34 0
|
9月前
|
存储 算法
算法训练Day18|● 513.找树左下角的值● 112. 路径总和 113.路径总和ii● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
算法训练Day18|● 513.找树左下角的值● 112. 路径总和 113.路径总和ii● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
|
11月前
|
Python
Python实现统计二叉树叶子结点个数
Python实现统计二叉树叶子结点个数
148 0
|
11月前
|
存储 算法 Java
代码随想录训练营day18| 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树...
代码随想录训练营day18| 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树...