Day14 | 找树左下角的值 路径总和 从中序与后序遍历序列构造二叉树

news2024/9/21 11:11:12

语言

Java

找树左下角的值

题目链接:找树左下角的值

题目

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

思路

本题有两种做法我主要讲一下递归的思路,创建两个全局变量,一个用于存树的深度,一个用于记录最下层最左树的值depth。

递归终止条件:树的左右子树都为空。 递归参数:节点,深度。

单层递归:先判断左右子树是否为空,为空了代表下面没有子树了,这时比较当前深度和全局变量的深度哪个大,当前深度大的话赋值给全局变量,也把值赋值给depth.然后判断左子树是否为空不为空的话进行递归,需要进行回溯操作。右子树同理。具体细节看代码。

代码

递归法

class Solution {
    int Deep = -1;
    int value = 0;//全局变量记录左下角的值
    public int findBottomLeftValue(TreeNode root) {
        findLeftValue(root, 0);
        return value;
    }
    public void findLeftValue(TreeNode root, int deep) {
        if (root.left == null && root.right == null) {
            if (deep > Deep) {
                Deep = deep;
                value = root.val;
            }
        }
        if (root.left != null) {
            deep++;
            findLeftValue(root.left, deep);
            deep--;
        }
        if (root.right != null) {//回溯
            deep++;
            findLeftValue(root.right, deep);
            deep--;
        }
    }
}

迭代法

class Solution {
    public int findBottomLeftValue(TreeNode root) {
        Queue<TreeNode> que = new LinkedList<>();
        int res = 0;
        que.offer(root);
        while (!que.isEmpty()) {
            int len = que.size();
            for (int i = 0; i < len; i++) {
                TreeNode tempNode = que.poll();
                if (i == 0) {
                    res = tempNode.val;
                }
                if (tempNode.left != null) {
                    que.offer(tempNode.left);
                }
                if (tempNode.right != null) {
                    que.offer(tempNode.right);
                }
            }
        }
        return res;
    }
}

易错点

递归法时要注意全局变量,还有回溯的过程。

路径总和

题目链接:路径之和

题目链接113. 路径总和ii

题目

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

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

思路

采用递归的方法,传入的值是targetSum,对它进行减减,如果节点的左右子树都为空且targetsum为0返回TRUE,分别向左和右递归,最后没找到的话返回false.

代码

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

易错点

先判断根节点是否为空再进行减减操作。

扩展

做完路径之和后,二也就会做了。不用返回true了,是将所有路径都遍历一遍。找出符合的

class Solution {
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> res = new ArrayList<>();//结果数组
        if (root == null) return res;//非空判断

        List<Integer> path = new LinkedList<>();
        traversal(root, targetSum, res, path);
        return res;
    }
    public void traversal(TreeNode root, int targetSum, List<List<Integer>> res,List<Integer> path) {
        path.add(root.val);
        if (root.left == null && root.right == null) {
            if (targetSum - root.val == 0) {
                res.add(new ArrayList(path));
            }
            return;
        }
        if (root.left != null) {
            traversal(root.left, targetSum - root.val, res, path);
            path.remove(path.size() - 1);//回溯
        }
        if (root.right != null) {
            traversal(root.right, targetSum - root.val, res, path);
            path.remove(path.size() - 1);
        }
    } 
}

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

题目链接:从中序和后序遍历构造函数

题目

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

思路

用一个Map存经过中序数组遍历出值和索引,开始递归

从后序遍历中找出根节点也就是最后一个,在中序遍历中找到它的索引。

开始切割根节点左边的是左子树,右边的是右子树。

代码

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 findNode(inorder, 0 ,inorder.length, postorder, 0, postorder.length);
    }
    public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
        if (inBegin >= inEnd || postBegin >= postEnd) {
            return null;
        }
        int rootIndex = map.get(postorder[postEnd - 1]);
        TreeNode root = new TreeNode(inorder[rootIndex]);
        int lenLeftOf = rootIndex - inBegin;
        root.left = findNode(inorder, inBegin, rootIndex, postorder, postBegin, postBegin + lenLeftOf);
        root.right = findNode(inorder, rootIndex + 1, inEnd, postorder, postBegin + lenLeftOf, postEnd - 1);
        return root;
    }
}

易错点

递归右子树的参数传递,后序遍历的时候无需在遍历最后一个节点了。

扩展

做完中序和后序,下面试一试前序和中序。

class Solution {
    Map <Integer, Integer> map;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        map = new HashMap<>();
        for (int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        return findNode(inorder, 0 ,inorder.length, preorder, 0, preorder.length);
    }
    public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] preorder, int preBegin, int preEnd) {
        if (inBegin >= inEnd || preBegin >= preEnd) {
            return null;
        }
        int rootIndex = map.get(preorder[preBegin]);
        TreeNode root = new TreeNode(inorder[rootIndex]);
        int lenLeftOf = rootIndex - inBegin;
        root.left = findNode(inorder, inBegin, rootIndex, preorder, preBegin + 1, preBegin + lenLeftOf + 1);
        root.right = findNode(inorder, rootIndex + 1, inEnd, preorder, preBegin + lenLeftOf + 1, preEnd);
        return root;
    }
}

 

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

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

相关文章

blender使用(三)常用建模操作及修改器

1&#xff0c;挤出图形 tab编辑模式&#xff0c;选中一个点/线/面&#xff0c;按键E&#xff0c;可以挤出对应的图形。选中点会挤出一条线&#xff0c;线会挤出一个面&#xff0c;面挤出体 2&#xff0c;倒角 选中一个边后&#xff0c;ctrlB &#xff0c;拖动鼠标是倒角范围&am…

MINIO集群部署手册

为了满足电子仓库功能相关部署与扩容等操作&#xff0c;因此提供电子仓库部署手册。手册中我们以2个minio节点&#xff0c;每个节点2个盘来进行分布式部署&#xff1b;并且最终扩容成4个节点每个节点2个盘。 操作系统 由于在Windows下运行分布式Minio处于实验阶段&#xff0c;因…

Web前端浅谈ArkTS组件开发

本文由JS老狗原创。 有幸参与本厂APP的鸿蒙化改造&#xff0c;学习了ArkTS以及IDE的相关知识&#xff0c;并有机会在ISSUE上与鸿蒙各路大佬交流&#xff0c;获益颇丰。 本篇文章将从一个Web前端的视角出发&#xff0c;浅谈ArkTS组件开发的基础问题&#xff0c;比如属性传递、插…

定积分与不定积分

定积分与不定积分 引言正文不定积分理解角度1理解角度2 定积分 引言 可能大家看到这个标题会不屑一顾&#xff0c;觉得这个还用你教我吗&#xff0c;高等数学最简单的内容。今天突然想到一个问题&#xff0c;就是为什么不定积分会有一个常数 C C C 出现&#xff0c;这个常数 …

继电器驱动电路的可靠性设计分析

在温度-30℃到85℃、供电电源9V-16V范围条件下&#xff0c;保证外部继电器能正常作动&#xff0c;且不发生负载能力降低的情况。&#xff08;注&#xff1a;需要详细的外部继电器规格说明&#xff09; 对于控制多路输出而且要求负载同时打开的模块&#xff0c;必须以50ms(10ms…

C++_单例模式

目录 1、饿汉方式实现单例 2、懒汉方式实现单例 3、单例模式的总结 结语 前言&#xff1a; 在C中有许多设计模式&#xff0c;单例模式就是其中的一种&#xff0c;该模式主要针对类而设计&#xff0c;确保在一个进程下该类只能实例化出一个对象&#xff0c;因此名为单例。而…

OpenCV 图像旋转和平移 数学和代码原理详解

文章目录 数学原理旋转矩阵平移和旋转合成变换矩阵应用在OpenCV中的实现 代码关键点解读完整代码C代码&#xff1a;Python代码&#xff1a; 在OpenCV中进行图像旋转涉及到一些基本的几何变换和图像处理操作。 数学原理 在图像旋转中&#xff0c;背后的数学原理主要涉及二维欧…

嵌入式硬件-Xilinx FPGA DDR4 接口配置基础(PG150)

1. 简介 1.1 DDR4 SDRAM 控制器主要特点 支持8到80位接口宽度的组件&#xff08;支持 RDIMM、LRDIMM、UDIMM 和 SODIMM&#xff09; 最大组件限制为9&#xff0c;此限制仅适用于组件&#xff0c;不适用于 DIMM。密度支持 最高支持 32 GB 的组件密度&#xff0c;64 GB 的 LRDI…

步步精慕尼黑上海电子展完美收官,感恩所有相遇,期待下次再会

2024年7月11日至13日&#xff0c;慕尼黑上海电子展圆满落幕&#xff0c;步步精科技&#xff08;以下简称步步精&#xff09;在此次展会上取得了丰硕的成果。作为连接器行业的重要制造商&#xff0c;步步精携带其最新产品和连接器技术方案亮相展会&#xff0c;吸引了大量参观者的…

【HarmonyOS】HarmonyOS NEXT学习日记:六、渲染控制、样式结构重用

【HarmonyOS】HarmonyOS NEXT学习日记&#xff1a;六、渲染控制、样式&结构重用 渲染控制包含了条件渲染和循环渲染&#xff0c;所谓条件渲染&#xff0c;即更具状态不同&#xff0c;选择性的渲染不同的组件。 而循环渲染则是用于列表之内的、多个重复元素组成的结构中。 …

RK3568笔记四十二:OLED 屏幕驱动(模拟I2C)

若该文为原创文章&#xff0c;转载请注明原文出处。 本篇记录使用GPIO模拟I2C驱动OLED屏幕&#xff0c;显示界面效果如下。 主要流程是&#xff0c;修改设备树&#xff0c;使用普通IO口&#xff0c;驱动模拟I2C方式&#xff0c;应用程直接传输数据控制。 1、修改设备 2、编写…

Go语言 Import导入

本文主要介绍Go语言import导入使用时注意事项和功能实现示例。 目录 Import 创建功能文件夹 加法 减法 主函数 优化导入的包名 .引入方法 总结 Import 创建功能文件夹 做一个计算器来演示&#xff0c;首先创建test文件夹。 加法 在test文件夹中创建add文件夹&#xff…

数据预处理在建模中的重要性与常见方法(三):特征工程篇

数据预处理在建模中的重要性与常见方法&#xff08;三&#xff09;&#xff1a;特征工程篇 特征工程是数据预处理中至关重要的一步&#xff0c;通过构建、转换和选择最能代表数据特性的特征&#xff0c;以提高模型的性能和准确性。常见的特征工程方法包括特征选择、特征提取和特…

前端-模拟请求数据mook第三方插件 json-server的使用

大纲 第一步下载第二配置mook的数据源第三配置启动命令第四运行模拟服务第五测试接口如果要进行更复杂的操作 第一步下载 npm install json-server -D"devDependencies": {"json-server": "^1.0.0-beta.1"}第二配置mook的数据源 在项目的根目录…

某指挥调度系统功能展示(下)

照片管理 拍照是普通执勤巡检中很常用的信息记录功能。 通过此功能可以看到设备本地拍摄的照片&#xff0c;此平台分成了两部分&#xff1a; 一部分是设备上的&#xff0c;需要设备在线才可以访问&#xff1b;支持上传到平台&#xff0c;并且在设备端有相应的选择&#xff0…

人、智能、机器人……

在遥远的未来之城&#xff0c;智能时代如同晨曦般照亮了每一个角落&#xff0c;万物互联&#xff0c;机器智能与人类智慧交织成一幅前所未有的图景。这座城市&#xff0c;既是科技的盛宴&#xff0c;也是人性与情感深刻反思的舞台。 寓言&#xff1a;《智光与心影》 在智能之…

Linux性能分析之-CPU篇

开发车载软件app&#xff0c;除了常用Android操作系统外&#xff0c;还可能是基于Linux系统开发。对于web应用基本也都部署在Linux系统上&#xff0c;所以&#xff0c;进行系统性能分析&#xff0c;很大情况下都是对Linux系统进行性能分析。此篇博客将重点介绍如果收集CPU相关指…

GPT-4o mini是什么?

今天&#xff0c;全网都知道 OpenAI 发现货了&#xff01; GPT-4o mini 取代 GPT 3.5&#xff0c;从此坐上正主之位。 从官网信息来看&#xff0c;OpenAI 最新推出的 GPT-4o mini 重新定义了 AI 成本效益的标准&#xff0c;其性能优于前代模型 GPT-3.5 Turbo&#xff0c;且成本…

SpringBoot系列—4.SpringBoot 整合Mybatis、MP(MyBatis-Plus)

SpringBoot系列—1.IDEA搭建SpringBoot框架 SpringBoot系列—2.SpringBoot拦截器篇 SpringBoot系列—3.SpringBoot Redis篇 SpringBoot系列—4.SpringBoot 整合Mybatis、MP&#xff08;MyBatis-Plus&#xff09; SpringBoot系列—5.SpringBoot 整合Mybatis-Plus分页 **1.pom.xm…

设计模式-Git-其他

目录 设计模式&#xff1f; 创建型模式 单例模式&#xff1f; 啥情况需要单例模式 实现单例模式的关键点&#xff1f; 常见的单例模式实现&#xff1f; 01、饿汉式如何实现单例&#xff1f; 02、懒汉式如何实现单例&#xff1f; 03、双重检查锁定如何实现单例&#xff…