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);
    }
};

总结


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

相关文章
|
前端开发 JavaScript Java
前端 NUXT框架
前端 NUXT框架
203 0
|
JavaScript 前端开发
HTML VSCode 自用插件列表 (包含Vue)
HTML VSCode 自用插件列表 (包含Vue)
410 0
|
开发工具 Android开发 iOS开发
2023年APP备案操作教程 阿里云APP备案试列 APP公钥sha1签名获取方法
核心要点:A,域名之前是哪里备案的,APP备案就到哪里去做,方便简单;B,APP备案核心预存信息为APP包名、MD5指纹(安卓)、sha1签名(IOS)、公钥;这3个信息请找APP开发人员获取;一门开发的可以自行到开发者后台【配置】-【证书与包名】获取对应安卓、苹果APP信息。
|
前端开发
前端引入字体文件
文章介绍了如何在前端项目中引入字体文件,并展示了具体的HTML和CSS代码示例,包括如何使用`@font-face`规则来定义字体和在页面中应用自定义字体。
443 1
前端引入字体文件
|
8月前
|
算法 搜索推荐
快速排序-数据结构与算法
快速排序(Quick Sort)是一种基于分治法的高效排序算法。其核心思想是通过选择基准(pivot),将数组划分为左右两部分,使得左侧元素均小于基准,右侧元素均大于基准,然后递归地对左右两部分进行排序。时间复杂度平均为 O(n log n),最坏情况下为 O(n²)(如数组已有序)。空间复杂度为 O(1),属于原地排序,但稳定性不佳。 实现步骤包括编写 `partition` 核心逻辑、递归调用的 `quickSort` 和辅助函数 `swap`。优化方法有随机化基准和三数取中法,以减少最坏情况的发生。
583 13
|
11月前
|
人工智能 机器人 API
AppFlow:无代码部署Dify作为钉钉智能机器人
本文介绍如何通过计算巢AppFlow完成Dify的无代码部署,并将其配置到钉钉中作为智能机器人使用。首先,在钉钉开放平台创建应用,获取Client ID和Client Secret。接着,创建消息卡片模板并授予应用发送权限。然后,使用AppFlow模板创建连接流,配置Dify鉴权凭证及钉钉连接凭证,完成连接流的发布。最后,在钉钉应用中配置机器人,发布应用版本,实现与Dify应用的对话功能。
2302 7
AppFlow:无代码部署Dify作为钉钉智能机器人
|
JSON 网络协议 Java
cpolar内网穿透将本地服务端接口模拟公共网络环境远程调用调试
cpolar内网穿透将本地服务端接口模拟公共网络环境远程调用调试
599 0
|
前端开发
基于jeecgboot的flowable流程任务excel导出功能
基于jeecgboot的flowable流程任务excel导出功能
291 1
|
JavaScript Linux 网络安全
若依修改,若依启动之后,网页端无法访问接口,宝塔和云服务器的端口都要放开,就好了,软件开发常见流程,后台端口就可以访问了
若依修改,若依启动之后,网页端无法访问接口,宝塔和云服务器的端口都要放开,就好了,软件开发常见流程,后台端口就可以访问了
|
数据库 流计算
Flink CDC的工作原理是通过监听数据库的变更事件
Flink CDC的工作原理是通过监听数据库的变更事件
410 1