代码随想录Day15 二叉树 LeetCodeT513 找树左下角的值 T112路径总和 T106 从中序和后序遍历构造二叉树

news2024/11/16 10:41:04

以上思路来自于:代码随想录 (programmercarl.com)

LeetCode T513 找树左下角的值

题目思路:

本题思路:这题我们使用递归法和迭代法解决问题

注意:左下角的值不一定就是一直向左遍历的叶子结点的值,首先可以确定是最后一行的第一个叶子结点的值,也就是最大深度的叶子结点的值

定义最大深度Deep变量,返回值result

1.递归法

前序遍历为例

1.1 确定递归的返回值和参数类型

我们这里不需要返回值,传入参数是节点和深度

void travelsal(TreeNode node,int deep)

1.2 确定终止条件

这里我们遇到一次叶子结点就更新一次最大深度,并记录下该节点的val

     if(node.left == null && node.right == null)
        {
            if(deep>Deep)
            {
                Deep = deep;
                result = node.val;
            }
           
        }

1.3 实现一次递归

    if(node.left != null)
        {
            travelsal(node.left,deep+1);

        }
        if(node.right != null)
        {
            travelsal(node.right,deep+1);
        }

2.迭代法

思路:使用层序遍历,找到最后一行,记录下最左边节点的数值

1.使用队列结构,队列不为空就继续,先加入根节点,接着我们用一个临时节点记录一下正在遍历的节点,方便取值,使用for循环,遍历每一层,记录下每一层第一个值,如果不是叶子节点就继续入队,详细思路可以看 层序遍历章节

代码解析:

public int findBottomLeftValue(TreeNode root) {
        //迭代法
       int result = 0;
       Queue<TreeNode> que = new LinkedList<>();
       que.offer(root);
       while(!que.isEmpty())
       {
           int size = que.size();
           for(int i = 0;i<size;i++)
           {
               TreeNode tmp = que.poll();
               if(i == 0)
               {
                   result = tmp.val;
               }
               if(tmp.left != null)
               {
                  que.offer(tmp.left);
               }
               if(tmp.right != null)
               {
                   que.offer(tmp.right);
               }
           }

       }
       return result;

    }
}

题目代码:

class Solution {
    int Deep = -1;
    int result = 0;
    public int findBottomLeftValue(TreeNode root) {
        result = root.val;
        travelsal(root,0);
        return result;
       

    }
    void travelsal(TreeNode node,int deep)
    {
        if(node == null)
        {
            return;
        } 
        if(node.left == null && node.right == null)
        {
            if(deep>Deep)
            {
                Deep = deep;
                result = node.val;
            }
           
        }
        if(node.left != null)
        {
            travelsal(node.left,deep+1);

        }
        if(node.right != null)
        {
            travelsal(node.right,deep+1);
        }

    }
}

LeetCode T112 路径总和

题目链接:112. 路径总和 - 力扣(LeetCode)

题目思路:

思路其实很简单,我们只需要遍历二叉树在叶子节点的时候判断即可,但是还是有很多细节需要注意,我们分一下几步操作,判断节点是否为空,减去该节点的值,判断叶子结点的值,下面就是递归的过程

1.判断头结点

    if(root == null)
        {
            return false;
        }

2.叶子节点

        //叶子结点
        if(root.left == null && root.right == null)
        {
            return targetSum == 0;
        }

3.递归过程

         //递归逻辑
        if(root.left != null)
        {
            boolean left = hasPathSum(root.left,targetSum);
            if(left)
            {
                return true;
            }
        }
        if(root.right != null)
        {
            boolean right = hasPathSum(root.right,targetSum);
            if(right)
            {
                return true;
            }
        }

注:我们这里用目标值一直往下减,如果到叶子节点发现值减到0就说明成功了,注意回溯的过程这里省略了.

题目代码:

class Solution {  
    public boolean hasPathSum(TreeNode root, int targetSum) {  
        //终止条件
        if(root == null)
        {
            return false;
        }
        targetSum -= root.val;
        //叶子结点
        if(root.left == null && root.right == null)
        {
            return targetSum == 0;
        }
        //递归逻辑
        if(root.left != null)
        {
            boolean left = hasPathSum(root.left,targetSum);
            if(left)
            {
                return true;
            }
        }
        if(root.right != null)
        {
            boolean right = hasPathSum(root.right,targetSum);
            if(right)
            {
                return true;
            }
        }
        return false;

    }  
}

T106 从中序和后序遍历构造二叉树

题目链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

 

题目思路:

这题思路较为简单,代码较长,我们举一个例子

我们首先根据后序的左右中来切割中序数组,就能知道9是左子树,15 20 7是右子树

然后根据右子树判断中节点是20,20的左节点是15右节点是7,我们就能唯一确定一个二叉树

这里我们分为以下几步处理

1.创建一个map来便于查找

2.将inorder的数据保存到map中 (key是数值,value是下标)

3.接着我们使用递归来实现

4.确定参数和返回值

public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) 

5.终止条件(注意这里切分区间要统一,使用闭区间还是左开右闭区间)

 if (inBegin >= inEnd || postBegin >= postEnd) {  // 不满足左闭右开,说明没有元素,返回空树
            return null;
        }

6.单次递归

        int rootIndex = map.get(postorder[postEnd - 1]);  // 找到后序遍历的最后一个元素在中序遍历中的位置
        TreeNode root = new TreeNode(inorder[rootIndex]);  // 构造结点
        int lenOfLeft = rootIndex - inBegin;  // 保存中序左子树个数,用来确定后序数列的个数
        root.left = findNode(inorder, inBegin, rootIndex,
                            postorder, postBegin, postBegin + lenOfLeft);
        root.right = findNode(inorder, rootIndex + 1, inEnd,
                            postorder, postBegin + lenOfLeft, postEnd - 1);

题目代码:

class Solution {
    Map<Integer,Integer> map;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for(int i = 0;i<inorder.length;i++)
        {
            map.put(inorder[i],i);
        }
        return FindOrder(inorder,0,inorder.length,postorder,0,postorder.length);

    }
    public TreeNode FindOrder(int[] inOrder,int inBegin,int inEnd,int[] postOrder,int postBegin,int postEnd)
    {
        //结束条件,这里我使用左闭右开写
        if(inBegin>=inEnd || postBegin>=postEnd)
        {
            return null;
        }
        //找到后序在中序的位置
        int index = map.get(postOrder[postEnd - 1]);
        //构造节点
        TreeNode root = new TreeNode(inOrder[index]);
        //保存中序左子树的个数,用来确定后序的区间
        int lenOfLeft = index - inBegin;
        root.left = FindOrder(inOrder,inBegin,index,postOrder,postBegin,postBegin+lenOfLeft);
        root.right = FindOrder(inOrder,index+1,inEnd,postOrder,postBegin+lenOfLeft,postEnd-1);
        return root;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1077341.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flask入门

第一个Flask项目 创建后项目如下图 static存放静态文件&#xff0c;templates存放Jinja2模板&#xff0c;app.py是整个项目的入口文件 我们略微理解下app.py这里的代码 # 从flask这个包中导入Flask类 from flask import Flask#使用Flask类创建一个app对象 #__name__:代表当前…

Linux下kibana的安装与配置

1. 环境配置 确保Linux服务器上已安装Java 8或更高版本。可以通过运行 java -version 来验证Java的版本。 下载Kibana 7.17.11的压缩文件&#xff0c;可以从Kibana 7.17.11下载 上传服务器&#xff0c;并解压Kibana压缩文件。 2. Kibana配置 编辑Kibana的配置文件 config/k…

JS中使用递归的一次探索

什么是递归&#xff1a;递归的思想是把一个大型复杂问题层层转化为一个与原问题规模更小的问题&#xff0c;问题被拆解成子问题后&#xff0c;递归调用继续进行&#xff0c;直到子问题无需进一步递归就可以解决的地步为止。 说白话就是函数自己调自己。 再翻译白话&#xff1…

【Unity ShaderGraph】| 如何快速制作一个炫酷 模型裁剪效果 实战

前言 【Unity ShaderGraph】| 如何快速制作一个炫酷 模型裁剪效果 实战一、效果展示二、简易裁剪效果三、进阶裁剪效果四、应用实例 前言 本文将使用Unity 的ShaderGraph制作一个模型裁剪的效果&#xff0c;可以直接拿到项目中使用。对ShaderGraph还不了解的小伙伴可以参考这篇…

练[CISCN2019 华东南赛区]Double Secret

[CISCN2019 华东南赛区]Double Secret 文章目录 [CISCN2019 华东南赛区]Double Secret掌握知识解题思路关键paylaod 掌握知识 ​ flask框架报错源码泄露&#xff0c;使用脚本进行RC4加解&#xff0c;ssti使用内置函数进行模板注入 解题思路 打开网站链接&#xff0c;页面就一…

【LeetCode75】第六十九题 或运算的最小翻转次数

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们 a&#xff0c;b&#xff0c;c 三个数&#xff0c;我们可以对 a 和 b 的二进制形态中的任何一位做翻转&#xff0c;问我们最少…

MobileViT v2导出onnx模型时遇Col2Im算子无法导出问题

相关error log索引 onnxruntime.capi.onnxruntime_pybind11_state.InvalidGraph: [ONNXRuntimeError] : 10 : INVALID_GRAPH : This is an invalid model. In Node, ("/classifier/classifier.0/ReduceMean", ReduceMean, "", -1) : ("/layer_5/laye…

hive3.1核心源码思路

系列文章目录 大数据主要组件核心源码解析 文章目录 系列文章目录大数据主要组件核心源码解析 前言一、HQL转化为MR 核心思路二、核心代码1. 入口类&#xff0c;生命线2. 编译代码3. 执行代码 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 对大…

UUID和雪花(Snowflake)算法该如何选择?

博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&#xff0c;探索全栈开发&#xff0c;期待与您一起在移…

嵌入式养成计划-38----C++--匿名对象--友元--常成员函数和常对象--运算符重载

八十七、匿名对象 概念&#xff1a;没有名字对象格式 &#xff1a;类名&#xff08;&#xff09;;作用 用匿名对象给有名对象初始化的用匿名对象给对象数组初始化的匿名对象作为函数实参使用 示例 : #include <iostream> using namespace std; class Dog { private:s…

小程序如何设置各种时间参数

在小程序管理员后台->基本设置处&#xff0c;可以设置各种时间。例如待支付提醒时间、待支付取消时间、自动发货时间、自动收货时间、自动评价时间等等。下面具体解释一下各个时间的意思。 1. 待支付提醒时间&#xff1a;在用户下单后&#xff0c;如果一段时间内没有完成支付…

IDEA的使用(一)代码模块的导入、快捷使用、自定义 (IntelliJ IDEA 2022.1.3版本)

目录 1. IDEA项目结构 2. 模块的导入操作 2.1 正规操作 2.2 取巧操作 2.3 出现乱码 2.4 模块改名 3. 代码模板的使用 后缀补全&#xff08;Postfix Completion&#xff09;、实时模板&#xff08;Live Templates&#xff09;菜单里面什么介绍都有&#xff0c;可以自学&a…

C#(Csharp)我的基础教程(四)(我的菜鸟教程笔记)-Windows项目结构分析、UI设计和综合事件应用的探究与学习

目录 windows项目是我们.NET学习一开始必备的内容。 1、窗体类&#xff08;主代码文件窗体设计器后台代码文件&#xff09; 主窗体对象的创建&#xff1a;在Program类里面&#xff1a; Application.Run(new FrmMain());这句代码就决定了&#xff0c;当前窗体是项目的主窗体。…

Python Opencv实践 - 车辆识别(1)读取视频,移除背景,做预处理

示例中的图像的腐蚀、膨胀和闭运算等需要根据具体视频进行实验得到最佳效果。代码仅供参考。 import cv2 as cv import numpy as np#读取视频文件 video cv.VideoCapture("../../SampleVideos/Traffic.mp4") FPS 10 DELAY int(1000 / FPS) kernel cv.getStructu…

Python数据容器——字典的常用操作(增、删、改、查)

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;Python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注. 目录 一、理解字典 1. Python字典是什么&#xff1f; 2. 字…

隆重宣布:.NET 8 RC1 现已推出

作者&#xff1a;Leslie Richardson 排版&#xff1a;Alan Wang .NET 8 RC1 现已推出。这是我们两个候选版本中的第一个。此版本包括适用于 Android 和 WASM 的新 AOT 模式、System.Text.Json 改进以及对容器的 Azure Managed Identity 支持。如果您还没有开始学习和测试 .NET …

基于Java+SpringBoot+Vue民宿管理系统的设计与实现 前后端分离【Java毕业设计·文档报告·代码讲解·安装调试】

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

android Google官网 :支持不同的语言和文化 rtl / ltr : 本地化适配:RTL(right-to-left) 适配

参考 google官网&#xff1a; 支持不同的语言和文化 应用包含可能专门针对特定文化而设计的资源。例如&#xff0c;应用可以包含针对特定文化的字符串&#xff0c;这些字符串将转换为当前语言区域的语言。 将具有文化特异性的资源与应用的其他资源分开是一种很好的做法。And…

Apache Doris 数据建模之 Aggregate Key 模型

了解 Doris 数据模型对于我们使用 Doris 来解决我们业务问题非常重要&#xff0c;这个系列我们将详细介绍 Doris 的三种数据模型及 Doris 数据分区分桶的一些策略&#xff0c;帮助用户更好的使用 Doris 。 这个系列我会讲解 Doris 的三种数据模型及在这三种数据模型之上的 Rol…

算法练习11——买卖股票的最佳时机 II

122. 买卖股票的最佳时机 II 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&#xff0c;然后在 同一天 出售。 返回 你能获得…