从二叉搜索树到更大和树 : BST 中序遍历的经典运用

题目描述

这是 LeetCode 上的 「1038. 从二叉搜索树到更大和树」 ,难度为 「中等」

Tag : 「BST」、「中序遍历」

给定一个二叉搜索树 root (BST),请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和。

提醒一下, 二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键小于节点键的节点。
  • 节点的右子树仅包含键大于节点键的节点。
  • 左右子树也必须是二叉搜索树。

示例 1: alt

输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]

输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

示例 2:

输入:root = [0,null,1]

输出:[1,null,1]

提示:

  • 树中的节点数在 范围内。
  • 树中的所有值均不重复 。

中序遍历

利用 BST 的中序遍历是有序」 的特性,我们可以通过两次遍历 BST 来求解问题。

首先,通过一次遍历,计算出整棵树的节点总和 tot,然后在中序遍历过程中,不断对 tot 进行更新,将其作为当前未遍历到的节点的总和,用于给当前节点赋值。

假设当前遍历到的节点为 x(起始节点值为 t),那么将节点更新为当前节点 tot 后,更新 tot = tot - t

这是常规的中序遍历做法,更进一步,如果将其中序遍历的顺序进行翻转(从「左中右」调整为「右中左」),则可实现一次遍历。

Java 代码:

class Solution {
    int tot = 0;
    public TreeNode bstToGst(TreeNode root) {
        dfs(root);
        return root;
    }
    void dfs(TreeNode root) {
        if (root == nullreturn ;
        dfs(root.right);
        tot += root.val;
        root.val = tot;
        dfs(root.left);
    }
}

C++ 代码:

class Solution {
public:
    int tot = 0;
    TreeNode* bstToGst(TreeNode* root) {
        dfs(root);
        return root;
    }
    void dfs(TreeNode* root) {
        if (root == nullptrreturn;
        dfs(root->right);
        tot += root->val;
        root->val = tot;
        dfs(root->left);
    }
};

Python 代码:

class Solution:
    def bstToGst(self, root: TreeNode) -> TreeNode:
        tot = 0
        def dfs(root):
            nonlocal tot
            if not root: return
            dfs(root.right)
            tot += root.val
            root.val = tot
            dfs(root.left)
        dfs(root)
        return root

TypeScript 代码:

function bstToGst(root: TreeNode | null): TreeNode | null {
    let tot = 0;
    const dfs = function(root: TreeNode | null): void {
        if (!root) return ;
        dfs(root.right);
        tot += root.val;
        root.val = tot;
        dfs(root.left);
    }
    dfs(root);
    return root;
};
  • 时间复杂度:
  • 空间复杂度:

最后

这是我们「刷穿 LeetCode」系列文章的第 No.1038 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地 🎉🎉

本文由 mdnice 多平台发布

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

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

相关文章

android通过广播打印RAM信息

通过广播打印ram相关log 参数说明: 广播:com.android.settings.action.RAM_INFO int型参数index:0 - 3h, 1 - 6h, 2 - 12h, 3 - 24h 代表过去时间app使用ram情况(平均/最大占用) Index: frameworks/base/services/cor…

Django 中的 HMAC 请求签名校验与 Vue.js 的完美协作

在 Web 应用的开发过程中,确保数据传输的安全性和完整性是一个不容忽视的问题。使用 HMAC(Hash-based Message Authentication Code)算法对请求内容进行签名校验,是一种常见且有效的安全策略。本文将详细介绍如何在 Django 后端实现 HMAC 签名校验,并展示如何在前端 Vue.j…

2023-简单点-树莓派中的硬件通讯

树莓派中的通讯方式 串口通讯什么是串口通讯?串口通讯的特点 tips并行通讯?基于网络的通讯?socket通讯 串口通讯 什么是串口通讯? 串行通信每次传输一个位元数据,并在连续进行单次过程的基础上进行通信。根据数据的传送方向&am…

leetcode_1094 拼车

1. 题意 有n段旅程,每段旅程由上车点、下车点、上车人数组成。 求给定的旅程是否能让所有旅程顺利完成。 拼车 2. 题解 首先肯定要将旅程按上车位置进行排序。 2.1 模拟小根堆 根据下车时间的早晚创建一个小根堆。 在每次进行新的旅程前判断是否有人下车了&am…

基于SSM+SpringBoot+Vue小区车位租赁系统

[技术实现] 小区车位租赁系统是使用SSMSpringBootVue前后端分离的管理系统。使用Spring框架可以在自动注入项目层级之间的调用对象,方便解耦,SpringMVC是体现了MVC设计思想的轻量级web框架,对web层进行解耦,使开发更简洁,MyBatis…

难以置信,一个小小的需求让我捣鼓出一个提效的网站来

难以置信,一个小小的需求让我捣鼓出一个提效的网站来 需求介绍 事情是这样的,有个群友在业务当中碰到一个小小的需求,需求是这样的: 页面当中存在多个输入框,输入框的 value 值是一个数值组成的字符串(盲猜应该是身份…

关于开展人工智能专业人员“计算机视觉处理设计开发工程师”专项培训的通知

“人工智能技术与咨询”发布 工业与信息化部电子工业标准化研究院于2022年7月1日发布《人工智能从业技术人员要求》,现针对已发布标准于1月3日至7日在北京举办《自然语言与语音处理设计开发工程师》中级人才培养,下边是具体文件通知请大家查阅。行业人才…

CentOS7 关于 SELinux 的常用操作

SELinux(Security-Enhanced Linux)是一个安全增强的 Linux 内核模块,用于提供更强大的访问控制和强制访问控制(MAC)机制。它通过在内核层面对进程和文件进行标记,并强制执行访问策略,提供了额外…

对一个多维随机变量作为线性变换以后的协方差矩阵

假设是一个n维的随机变量,它的协方差矩阵 对做线性变换,其中是一个矩阵(当然也可以是一个标量),的协方差矩阵 证明如下: 将代入,得

游戏配置表的导入使用

游戏配置表是游戏策划的标配,如下图: 那么程序怎么把把这张配置表导入使用? 1.首先,利用命令行把Excel格式的文件转化成Json格式: json-excel\json-excel json Tables\ Data\copy Data\CharacterDefine.txt ..\Cli…

构建满足流批数据质量监控用火山引擎DataLeap

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 面对今日头条、抖音等不同产品线的复杂数据质量场景,火山引擎 DataLeap 数据质量平台如何满足多样的需求?本文将介绍我们在弥合大数据场景下…

Apache Flink(六):Apache Flink快速入门 - Flink案例实现

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录

uniapp自定义进度条组件

目标效果 原型设计为这样的样式&#xff0c;但是现有的进度条都无法满足需求&#xff0c;于是编写组件实现。 设计引用格式为 <zLineProgress :total"15" :val"7" title"你好吗" />定义组件 <template><view style"hei…

Es6新特性

一、 let 声明变量 不能重复声明有块级作用域&#xff08;不影响作用域链&#xff0c;函数里可以拿到函数外的变量&#xff09;不存在变量提升 经典案列&#xff1a;&#xff08;把for里面的var i 0; 改成 let i 0就好了&#xff0c;不然items[i]就会报错&#xff09; 二、…

Mars3d标绘的时候通过绑定单击事件,查询点击落点的图层类型

需求期望&#xff1a; 期望可以判断标绘点落下的位置是什么图层类型&#xff0c;例如是否是3dtitles模型&#xff0c;或者是gltf模型&#xff0c;或者是其他数据图层。 需求来源&#xff1a; 标绘点时&#xff0c;无法知道点落下的地方的图层类型 解决方案&#xff1a; ma…

C++ string类(1)—初始化、容量操作、迭代器

目录 前言 一、string类 二、初始化 1、无参或带参 2、用字符串变量初始化 3、用字符串初始化 4、指定数量字符 三、容量操作 1、size 2、push_back 3、append​编辑 4、运算符 5、reserve 6、resize 四、迭代器 1、正向迭代器 2、反向迭代器 3、const迭代器…

排序算法介绍(四)快速排序

0. 简介 快速排序&#xff08;Quick Sort&#xff09;是一种高效的排序算法&#xff0c;采用了分治的思想。它选择一个基准元素&#xff0c;通过一趟排序将待排序序列分割成独立的两部分&#xff0c;其中一部分的所有元素都比基准元素小&#xff0c;另一部分的所有元素都比基准…

邦芒支招:管理者做好管理带团队的十大招数

如何做好一个团队的管理&#xff0c;俗话说&#xff1a;”得民心者得天下“&#xff0c;一个好的团队&#xff0c;应该做到以人为本&#xff0c;这样才能使团队和个人双双获益。接下来小邦给大家分享如何做好一个团队的管理。 ​ ​要做好一个团队的管理&#xff0c;需要关注…

iOS代码混淆工具

目录 引言 混淆效果 字符串加密 代码插入 其他混淆选项说明 总结 参考资料 &#x1f512; 这是一篇介绍iOS代码混淆工具的技术博客&#xff0c;旨在帮助开发者提高代码安全性。本工具来自于Github的混淆词库和代码&#xff0c;通过差异化处理和代码合并生成数亿种用于混淆…

激活函数的作用

目录 1. 激活函数的作用 2. 常见的激活函数类型 3. 激活函数的选择 4. 激活函数的影响 1. 激活函数的作用 激活函数在人工神经网络中扮演着至关重要的角色。它们的主要作用是为网络中的每个神经元引入非线性变换&#xff0c;这使得神经网络能够学习和执行非线性复杂的任务。…