LeetCode 剑指 Offer II 054. 所有大于等于节点的值之和

news2024/10/3 2:27:50

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

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

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

示例 1:
在这里插入图片描述
输入:root = [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]

树中的节点数介于 0 和 104 之间。
每个节点的值介于 -104 和 104 之间。
树中的所有值 互不相同 。
给定的树为二叉搜索树。

解法一:反向中序遍历树,每遍历到一个节点,将其加到所有节点和中,然后将该节点值设为当前所有节点和:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* convertBST(TreeNode* root) {
        if (root == nullptr) {
            return nullptr;
        }

        convertBST(root->right);
        sum += root->val;
        root->val = sum;
        convertBST(root->left);

        return root;
    }
private:
    int sum = 0;
};

如果树有n个节点,则此算法时间复杂度为O(n),空间复杂度平均情况下O(lgn),最差情况下为O(n),主要的空间开销是栈开销,当二叉搜索树退化成链表时,空间复杂度达到最大。

解法二:此解法是解法一的迭代版,用一个stack来模拟函数调用栈:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* convertBST(TreeNode* root) {
        stack<TreeNode *> s;
        TreeNode *curNode = root;
        while (curNode || !s.empty()) {
            while (curNode) {
                s.push(curNode);
                curNode = curNode->right;
            }

            curNode = s.top();
            s.pop();
            sum += curNode->val;
            curNode->val = sum;

            curNode = curNode->left;
        }

        return root;
    }
private:
    int sum = 0;
};

如果树有n个节点,则此算法时间复杂度为O(n),空间复杂度平均情况下O(lgn),最差情况下为O(n),主要的空间开销是栈开销,当二叉搜索树退化成链表时,空间复杂度达到最大。

解法三:Morris遍历,它的反向中序遍历的规则如下:
1.如果当前节点的右子节点为空,处理当前节点,并遍历当前节点的左子节点;

2.如果当前节点的右子节点不为空,找到当前节点右子树的最左节点(该节点为当前节点中序遍历的前驱节点);

(1)如果最左节点的左指针为空,将最左节点的左指针指向当前节点,遍历当前节点的右子节点;

(2)如果最左节点的左指针不为空,将最左节点的左指针重新置为空(恢复树的原状),处理当前节点,并将当前节点置为其左节点;

3.重复步骤1和步骤2,直到遍历结束。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* convertBST(TreeNode* root) {
        TreeNode *node = root;
        int sum = 0;

        while (node)
        {
            if (node->right == nullptr)
            {
                sum += node->val;
                node->val = sum;
                node = node->left;
            }
            else
            {
                TreeNode *mostLeftOfRight = getMostLeftOfRight(node);
                if (mostLeftOfRight->left == nullptr)
                {
                    mostLeftOfRight->left = node;
                    node = node->right;
                }
                else if (mostLeftOfRight->left == node)
                {
                    sum += node->val;
                    node->val = sum;
                    mostLeftOfRight->left = nullptr;
                    node = node->left;
                }
            }
        }

        return root;
    }

private:
    TreeNode *getMostLeftOfRight(TreeNode *node)
    {
        TreeNode *mostLeftOfRight = node->right;
        while (mostLeftOfRight->left && mostLeftOfRight->left != node)
        {
            mostLeftOfRight = mostLeftOfRight->left;
        }

        return mostLeftOfRight;
    }
};

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

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

相关文章

网络监测之如何保障企业业务系统安全?

网络信息安全在网络时代的重要性不言而喻。随着互联网的普及和数字化进程的加速&#xff0c;网络已经成为人们生活、工作和学习的重要平台。在这个平台上&#xff0c;信息交流、数据存储、在线支付等都需要依赖于网络信息安全。其中企事业单位业务系统安全值得关注。 企事业单…

前端未死,顺势而生

随着人工智能和低代码的崛起&#xff0c;“前端已死”的声音逐渐兴起。前端已死&#xff1f;尊嘟假嘟&#xff1f;快来发表你的看法吧&#xff01; 一、“前端已死”因何而来&#xff1f; 在开始讨论之前&#xff0c;首先要明确什么是“前端”。 所谓前端&#xff0c;主要涉及…

计算机图形学理论(3):着色器编程

本系列根据国外一个图形小哥的讲解为本&#xff0c;整合互联网的一些资料&#xff0c;结合自己的一些理解。 CPU vs GPU CPU支持&#xff1a; 快速缓存分支适应性高性能 GPU支持&#xff1a; 多个 ALU快速板载内存并行任务的高吞吐量&#xff08;在每个片段、顶点上执行着色…

概率中的 50 个具有挑战性的问题 [05/50]:正方形硬币

一、说明 我最近对与概率有关的问题产生了兴趣。我偶然读到了弗雷德里克莫斯特勒&#xff08;Frederick Mosteller&#xff09;的《概率论中的五十个具有挑战性的问题与解决方案》&#xff09;一书。我认为创建一个系列来讨论这些可能作为面试问题出现的迷人问题会很有趣。每篇…

Spring Security 6.x 系列(12)—— Form表单认证登录注销自定义配置

一、前言 在本系列文章中介绍了 Form 表单认证和注销流程&#xff0c;对部分源码也进行详细分析。 本章主要学习 Spring Security 中表单认证登录注销的相关自定义配置。 二、自定义登录页面 Spring Security 表单认证默认规则中对未认证的请求会重定向到默认登录页面&…

固定效应模型-以stata为工具

固定效应模型-以stata为工具 文章目录 1.固定效应模型2. 模型原理3. `stata`代码实现1.固定效应模型 固定效应模型(Fixed Effects Model)是一种面板数据分析方法,通过引入个体固定效应来控制个体间的异质性,并更准确地估计解释变量对因变量的影响。它在许多经济、社会科学…

快速剪辑视频软件,视频图像翻转软件

在这个信息爆炸的时代&#xff0c;视频已经成为了人们获取信息、娱乐、学习的主要方式之一。一个好的视频&#xff0c;不仅可以吸引观众的眼球&#xff0c;更可以传达出深层次的意义。那该什么快速的编辑视频&#xff0c;有没有好用的工具推荐呢&#xff1f;今天小编就给大家介…

Pytorch项目(模型训练与优化),肺癌检测项目之六

数据优化方案 数据优化方案1&#xff1a;重复抽样 &#xff08;1&#xff09;对多数类的样本实施欠采样&#xff0c;减少多数类数量 &#xff08;2&#xff09;对少数类的样本实施过采样&#xff0c;增加少数类数量 数据优化方案2&#xff1a;数据增强 数据增强&#xff08…

如何提升亚马逊、速卖通店铺自然排名?测评自养号的关键要素

一、自然排名的重要性 一条链接是否推广成功或者赚到钱&#xff0c;就看这条链接的自然排名有没有打上来! 无论是搜索流量的自然排名&#xff0c;还是关联流量的自然排名&#xff0c;或BSR排行榜&#xff0c;这些自然排名的入口就是我们要时刻盯紧的位置。 二、自然排名的位…

【数据库系统概论】第2章-关系数据库

复习记录 2.1 关系数据结构及形式化定义2.1.1 关系2.1.2 关系模式2.1.3 关系数据库 2.2 关系操作2.3 关系的完整性2.4 关系代数2.5 题目 2.1 关系数据结构及形式化定义 2.1.1 关系 一些概念 关系 R ( D 1 , D 2 , . . . , D n ) R(D_1,D_2,...,D_n) R(D1​,D2​,...,Dn​) …

Python----静态Web服务器-返回指定页面数据

1. 静态Web服务器的问题 目前的Web服务器&#xff0c;不管用户访问什么页面&#xff0c;返回的都是固定页面的数据&#xff0c;接下来需要根据用户的请求返回指定页面的数据 返回指定页面数据的实现步骤: 获取用户请求资源的路径根据请求资源的路径&#xff0c;读取指定文件…

Vue3数据交互axios

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 本…

【C++】function包装器全解(代码演示,例题演示)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Linux》…

【LearnOpenGL基础入门——6】纹理

目录 一.前言 二.纹理环绕方式 三.纹理过滤 四.多级渐远纹理 五.加载与创建纹理 六.生成纹理 七.应用纹理 八.纹理单元 一.前言 我们可以为每个顶点添加颜色来增加图形的细节&#xff0c;从而创建出有趣的图像。但是&#xff0c;如果想让图形看起来更真实&#xff0c;我…

vue3(六)-基础入门之自定义组件

一、全局组件 html: <div id"app"><mytemplace></mytemplace> </div>javascript: <script>const { createApp } Vueconst app createApp({})app.component(mytemplace, {template: <div><button>返回</button>…

智慧楼宇整体解决方案:PPT全文50页,附下载

关键词&#xff1a;智慧楼宇建设方案&#xff0c;智慧建筑建设方案&#xff0c;智慧楼宇控制系统&#xff0c;智慧楼宇解决方案&#xff0c;智慧建筑与建造&#xff0c;智慧建筑的定义 一、智慧楼宇背景分析 1、城市化进程加速&#xff1a;随着全球城市化率的提高&#xff0c…

敏捷开发 - 知识普及

敏捷开发- Scrum 前言 知乎有一篇文章描写Scrum,我觉得比较好:https://zhuanlan.zhihu.com/p/631459977 简单科普下PM和PMO 原文来源:https://zhuanlan.zhihu.com/p/546820914 PM - 项目经理(Project Manager) ​ 需要具备以下能力 ​ 1.号召力 2.影响力 3.交流能力 4.应…

三菱人机交互GT Designer的安装

今天&#xff0c;与小编一起来学习三菱的GT Designer软件&#xff0c;下面就是小编记录的软件查找&#xff0c;安装的全过程&#xff0c;希望对你学习三菱有帮助。 目录 安装 选择官网下载安装包 解压安装包进行安装 创建一个工程 安装 选择官网下载安装包 三菱&#xff08;中…

像素级调整,高效转换——轻松提升你的图片处理体验!

探索更高级的图片处理体验&#xff0c;我们为你带来像素级调整与高效转换的完美结合&#xff01;借助我们的专业工具&#xff0c;轻松调整图片像素&#xff0c;让你在细节处展现无限创意&#xff0c;提升作品质感。 第一步&#xff0c;进入首助编辑高手主页面&#xff0c;可以看…

电子学会C/C++编程等级考试2023年03月(六级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:波兰表达式 波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的波兰表示法为+ 2 3。波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的波兰表示法为* + 2 3 4。本…