代码随想录算法日记day16 | 513.找树左下角的值、112. 路径总和、106.从中序与后序遍历序列构造二叉树

news2024/12/22 18:28:35

原题链接&&讲解

222. 完全二叉树的节点个数
112. 路径总和
106.从中序与后序遍历序列构造二叉树
讲解>>代码随想录

222. 完全二叉树的节点个数

题目

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(从第 0 层开始),则该层包含 1~ 2h 个节点。

思路

法一:采用递归
法二:迭代

代码

// 递归
class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) {
            return 0;
        }
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}
class Solution {
    // 迭代法深度优先搜索
    public int countNodes(TreeNode root) {
        if (root == null) {
        	return 0;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        int result = 0;
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result++; // 计数当前节点
            // 如果有右子节点,压入栈中
            if (node.right != null) {
                stack.push(node.right);
            }
            // 如果有左子节点,压入栈中
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        return result;
    }
}
class Solution {
    // 迭代法深度优先搜索
    public int countNodes(TreeNode root) {
        if (root == null) {
        	return 0;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int result = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size-- > 0) {
                TreeNode cur = queue.poll();
                result++;
                if (cur.left != null) queue.offer(cur.left);
                if (cur.right != null) queue.offer(cur.right);
            }
        }
        return result;
    }
}

112. 路径总和

题目

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

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

思路

DFS思路:
从根节点开始,沿着每一条路径向下遍历,直到找到一条路径满足所有节点值之和等于 targetSum 或者遍历完所有可能的路径。
BFS思路:拿层先来做显然不是很合适, 不过也可以去实现, 要多加一个队列来方便计算和

代码

class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        // 如果当前节点为空,返回false
        if(root==null){
            return false;
        }
        // 否则,减去当前节点值
        targetSum -= root.val;
        // 检查是否为叶子节点并且路径和等于目标和
        if (root.left == null && root.right == null) {
            return targetSum == 0;
        }
        // 递归左右子树
        return hasPathSum(root.left, targetSum) || hasPathSum(root.right, targetSum);
    }
}
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if (root == null) {
            return false;
        }
        // 使用队列存储节点及其对应的路径和
        Queue<TreeNode> nodeQueue = new LinkedList<>();
        Queue<Integer> sumQueue = new LinkedList<>();
        nodeQueue.offer(root);
        sumQueue.offer(root.val);
        while (!nodeQueue.isEmpty()) {
            TreeNode currentNode = nodeQueue.poll();
            int currentSum = sumQueue.poll();
            // 检查是否为叶子节点并且路径和等于目标和
            if (currentNode.left == null && currentNode.right == null && currentSum == targetSum) {
                return true;
            }
            // 将左子节点及更新后的路径和加入队列
            if (currentNode.left != null) {
                nodeQueue.offer(currentNode.left);
                sumQueue.offer(currentSum + currentNode.left.val);
            }
            // 将右子节点及更新后的路径和加入队列
            if (currentNode.right != null) {
                nodeQueue.offer(currentNode.right);
                sumQueue.offer(currentSum + currentNode.right.val);
            }
        }
        return false;
    }
}

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

题目

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

思路

首先需要理解中序和后序遍历的含义, 这是必要的.

我们可以通过后序遍历的结果来确定根节点, 但是后序遍历无法确定根节点的左右子树
那么我们可以通过中序遍历来确定根节点的左右子树, 根节点已经在后序遍历中找到了.
就这样通过中序和后序遍历的配合, 我们可以逐个判断节点的位置, 将二叉树画出来.
那么接下来就是代码实现

步骤

  1. 确定根节点:
    后序遍历的最后一个元素是树的根节点。
  2. 分割左右子树:
    在中序遍历中找到根节点的位置,它左边的所有节点属于左子树,右边的所有节点属于右子树。
  3. 递归构造子树:
    根据中序遍历中根节点的位置,可以确定左右子树各自的中序和后序遍历序列。
    对于每个子树,重复步骤1和2的过程,即从后序遍历中找到子树的根节点,并在中序遍历中划分出更小的左右子树。
  4. 终止条件:
    当没有更多的节点用于构建子树时(即后序遍历或中序遍历为空),返回 null 表示当前递归分支结束。

代码

class Solution {
    private int postIndex;
    private HashMap<Integer, Integer> indexMap = new HashMap<>();
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        if (inorder == null || postorder == null || inorder.length != postorder.length) {
            return null;
        }
        postIndex = postorder.length - 1;
        // 构建索引映射以获取中序序列中值到索引的快速查找
        int idx = 0;
        for (Integer val : inorder) {
            indexMap.put(val, idx++);
        }
        return buildTreeHelper(inorder, postorder, 0, inorder.length - 1);
    }
    private TreeNode buildTreeHelper(int[] inorder, int[] postorder, int inLeft, int inRight) {
        // 如果没有元素构造子树了,则返回null
        if (inLeft > inRight) {
            return null;
        }
        // 选择 postIndex 位置元素作为当前子树根节点
        int rootValue = postorder[postIndex];
        TreeNode root = new TreeNode(rootValue);
        postIndex--;
        // 根据root所在中序的位置划分左右子树
        int index = indexMap.get(rootValue);
        // 先构造右子树,再构造左子树(因为后序遍历是“左->右->根”,所以从后往前)
        root.right = buildTreeHelper(inorder, postorder, index + 1, inRight);
        root.left = buildTreeHelper(inorder, postorder, inLeft, index - 1);
        return root;
    }
}

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

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

相关文章

学技术学英文:SpringBoot的内置监控组件-Spring Boot Actuator

导读&#xff1a; Spring Boot Actuator是Spring Boot提供的一个模块&#xff0c;简单配置后就能开启&#xff0c;属于拿来即用&#xff0c;具体功能如下&#xff1a; 监控和管理Spring Boot应用 Spring Boot Actuator提供了一组REST端点和命令行工具&#xff0c;用于查看应…

「Mac畅玩鸿蒙与硬件45」UI互动应用篇22 - 评分统计工具

本篇将带你实现一个评分统计工具&#xff0c;用户可以对多个选项进行评分。应用会实时更新每个选项的评分结果&#xff0c;并统计平均分。这一功能适合用于问卷调查或评分统计的场景。 关键词 UI互动应用评分统计状态管理数据处理多目标评分 一、功能说明 评分统计工具允许用…

压缩glb模型文件

使用?gltf-pipeline进行压缩&#xff1a; GitHub地址[这里是图片001]https://github.com/CesiumGS/gltf-pipeline 1. 安装gltf-pipeline npm install -g gltf-pipeline2. 在glb文件目录打开cmd进行命令行压缩&#xff1a; // cmd: gltf-pipeline -i glb.glb -d -s以下是 -…

创建SpringBoot项目的五种方式

1. 使用SpringBoot官方模板创建 1.1 IDEA集成创建 File > new Project 目前SpringBoot官方对于SpringBoot模板版本都比较新&#xff0c;所以对Java的依赖版本也很新&#xff0c;这里可以看到已经不支持jdk8了&#xff0c;并且只有SpringBoot3版本 我们选择好之后点击…

软件维护的实施

软件维护活动 (1) 维护机构 除了较大的软件开发公司外&#xff0c;通常在软件维护工作方面&#xff0c;不保持正式的维护机构。维护往往是在没有计划的情况下进行的。虽然不要求建立一个正式的维护机构&#xff0c;但是在开发部门&#xff0c;确立一个非正式的维护机构则是非常…

stm32 rtc 详解

目录 L151 RTC 唤醒代码 方式一 通过 RTC Alarm Interrupt&#xff1a;(基本和F1系列一样)&#xff1a; L151 RTC 唤醒代码 方式二 通过 RTC WakeUp Interrupt F103VE RTC 闹钟唤醒代码 &#xff08;103RC 没有闹钟中断&#xff09;&#xff1a; RTC&#xff08;real time…

arcgisPro相接多个面要素转出为完整独立线要素

1、使用【面转线】工具&#xff0c;并取消勾选“识别和存储面邻域信息”&#xff0c;如下&#xff1a; 2、得到的线要素&#xff0c;如下&#xff1a;

机器人国际会议IROS论文latex模板

机器人国际会议IROS论文latex模板 文档 root.tex 可以配置为 US Letter 纸或 A4。请注意以下重要行&#xff1a;\documentclass[letterpaper, 10 pt, Conference]{ieeeconf} % 如果需要 a4paper&#xff0c;请注释掉此行%\documentclass[a4paper, 10pt, Conference]{ieeeconf} …

JVM和数据库面试知识点

JVM内存结构 主要有几部分&#xff1a;堆、栈、方法区和程序计数器 堆是JVM中最大的一块内存区域&#xff0c;用于存储对象实例&#xff0c;一般通过new创建的对象都存放在堆中。堆被所有的线程共享&#xff0c;但是它的访问时线程不安全的&#xff0c;通常通过锁的机制来保证线…

数据结构:栈和队列的实现

栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。 栈中的数据元素遵守后进先出 LIFO &#xff08; Last In First Out &#xff09;的原则。 压栈&#xff1a;栈…

实现 WebSocket 接入文心一言

目录 什么是 WebSocket&#xff1f; 为什么需要 WebSocket&#xff1f; HTTP 的局限性 WebSocket 的优势 总结&#xff1a;HTTP 和 WebSocket 的区别 WebSocket 的劣势 WebSocket 常见应用场景 WebSocket 握手过程 WebSocket 事件处理和生命周期 WebSocket 心跳机制 …

开源轮子 - Logback 和 Slf4j

spring boot内置&#xff1a;Logback 文章目录 spring boot内置&#xff1a;Logback一&#xff1a;Logback强在哪&#xff1f;二&#xff1a;简单使用三&#xff1a;把 log4j 转成 logback四&#xff1a;日志门面SLF4J1&#xff1a;什么是SLF4J2&#xff1a;SLF4J 解决了什么痛…

MFC/C++学习系列之简单记录13

MFC/C学习系列之简单记录13 前言memsetList Control代码注意 总结 前言 今天记录一下memset和List control 的使用吧&#xff01; memset memset通常在初始化变量或清空内存区域的时候使用&#xff0c;可以对变量设定特定的值。 使用&#xff1a; 头文件&#xff1a; C&#…

Layui table不使用url属性结合laypage组件实现动态分页

从后台一次性获取所有数据赋值给 Layui table 组件的 data 属性&#xff0c;若数据量大时&#xff0c;很可能会超出浏览器字符串最大长度&#xff0c;导致渲染数据失败。Layui table 结合 laypage 组件实现动态分页可解决此问题。 HTML增加分页组件标签 在table后增加一个用于…

网络方案设计

一、网络方案设计目标 企业网络系统的构成 应用软件 计算平台 物理网络及拓扑结构 网络软件及工具软件 网络互连设备 广域网连接 无论是复杂的&#xff0c;还是简单的计算机网络&#xff0c;都包括了以下几个基本元素 &#xff1a; 应用软件----支持用户完成专门操作的软件。…

QT QWidget 背景颜色 鼠标hover 背景颜色研究

自定义控件 UserAvatarWidget 的样式问题及解决方案 场景描述 我开发了一个继承自 QWidget 的自定义控件 UserAvatarWidget&#xff0c;并在 .ui 文件中引入了该控件。引入代码如下&#xff1a; <item><widget class"UserAvatarWidget" name"userAv…

javaScriptBOM

1.1、BOM概述 1.1.1、BOM简介 BOM&#xff08;browser Object&#xff09;即浏览器对象模型&#xff0c;它提供了独立于内容而与浏览器窗口进行交互的对象&#xff0c;其核心对象是window。 BOM由一系列的对象构成&#xff0c;并且每个对象都提供了很多方法与属性 BOM缺乏标准…

【Lua热更新】上篇

Lua 热更新 - 上篇 下篇链接&#xff1a;【Lua热更新】下篇 文章目录 Lua 热更新 - 上篇一、AssetBundle1.理论2. AB包资源加载 二、Lua 语法1. 简单数据类型2.字符串操作3.运算符4.条件分支语句5.循环语句6.函数7. table数组8.迭代器遍历9.复杂数据类型 - 表9.1字典9.2类9.3…

AJAX与Axios

什么是 AJAX ? AJAX 是异步的 JavaScript 和 XML&#xff08;Asynchronous JavaScript And XML&#xff09;。 简单理解AJAX&#xff1a;是一种客户端与服务器进行网络通信技术&#xff0c;AJAX通常使用XMLHttpRequest 对象来发送请求和接收响应 现代开发中我们通常使用 JS…

1.gitlab 服务器搭建流程

前提条件&#xff1a; 一、服务器硬件水平 搭建gitlab服务器最低配置要求2核4G,低于这个配置的服务器运行效果很差。 gitlab官网&#xff1a;https://about.gitlab.com/ 下载地址&#xff1a;gitlab/gitlab-ce - Packages packages.gitlab.com 本机ubuntu 二、安装依赖 su…