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

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

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

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

示例 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.hqwc.cn/news/296197.html

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

相关文章

融资项目——swagger2的注解

1. ApiModel与ApiModelProperty(在实体类中使用) 如上图&#xff0c;ApiModel加在实体类上方&#xff0c;用于整体描述实体类。ApiModelProperty(value"xxx",example"xxx")放于每个属性上方&#xff0c;用于对属性进行描述。swagger2网页上的效果如下图&am…

VSCode运行时弹出powershell

问题 安装好了vscode并且装上code runner插件后&#xff0c;运行代码时总是弹出powershell,而不是在vscode底部终端 显示运行结果。 解决方法 打开系统cmd ,在窗口顶部条右击打开属性&#xff0c;把最下面的旧版控制台选项取消&#xff0c;即可

【Spring Security】打造安全无忧的Web应用--使用篇

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Spring Security的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Spring Security中的授权是…

MySQL 数据库系列课程 04:MySQL Workbench的安装

Workbench 是 MySQL 官方推出的免费的强大的可视化工具&#xff0c;不熟悉命令行工具的人&#xff0c;可以安装这一款软件&#xff0c;通过编写 SQL 进行数据库中数据的增删改查操作&#xff0c;接下来我们详细说明一下 Workbench 的安装。 一、Windows安装Workbench &#x…

【JavaWeb学习笔记】13 - JSP浏览器渲染技术

项目代码 https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/jsp JSP 一、JSP引入 1.JSP现状 1.目前主流的技术是前后端分离(比如: Spring Boot Vue/React),我们会讲的.[看一下] 2. JSP技术使用在逐渐减少&#xff0c;但使用少和没有使用是两个意思&#xff…

为什么react call api in cDidMount

为什么react call api in cDM 首先&#xff0c;放到constructor或者cWillMount不是语法错误 参考1 参考2 根据上2个参考&#xff0c;总结为&#xff1a; 1、官网就是这么建议的&#xff1a; 2、17版本后的react 由于fiber的出现导致 cWM 会调用多次&#xff01; cWM 方法已…

docker笔记1-安装与基础命令

docker的用途&#xff1a; 可以把应用程序代码及运行依赖环境打包成镜像&#xff0c;作为交付介质&#xff0c;在各种环境部署。可以将镜像&#xff08;image&#xff09;启动成容器&#xff08;container&#xff09;&#xff0c;并提供多容器的生命周期进行管理&#xff08;…

多线程的基本使用与多线程中条件变量的使用——消费者生产者问题实例

多线程的基本使用与多线程中条件变量的使用——消费者生产者问题实例 本文主要涉及多线程的使用方法&#xff0c;通过两个实例来对多线程的使用进行理解&#xff0c; 案例包括&#xff1a; 1.一个线程负责计数&#xff0c;另一个线程负责打印计数值 2.消费者生产者问题 文章目录…

flutter 实战 之 dio小实践

我们要对dio进行封装 class HttpRequest {static Future request(String url,{String method "get",Map<String,dynamic>? params})async{// 创建dio实例BaseOptions baseOptions BaseOptions(baseUrl: base_url,connectTimeout: Duration(seconds: 1));fi…

Pinely Round 3 (Div. 1 + Div. 2)(A~D)(有意思的题)

A - Distinct Buttons 题意&#xff1a; 思路&#xff1a;模拟从&#xff08;0,0&#xff09;到每个位置需要哪些操作&#xff0c;如果总共需要4种操作就输出NO。 // Problem: A. Distinct Buttons // Contest: Codeforces - Pinely Round 3 (Div. 1 Div. 2) // URL: https…

射频芯片CMT2310-DEMO 通信覆盖测试体验

CMT2310是一款超低功耗,高性能的射频收发器,申请一套原厂CMT2310演示demo来验证下Sub-868设备在国内城市环境通信覆盖效果。 城市道路实测情况 测试小结&#xff1a;设备已基于外置天线&#xff0c;且以最佳方位做验证&#xff0c;但测试结果数据不是很理想。

【12.23】转行小白历险记-算法02

不会算法的小白不是好小白&#xff0c;可恶还有什么可以难倒我这个美女的&#xff0c;不做花瓶第二天&#xff01; 一、螺旋矩阵 59. 螺旋矩阵 II - 力扣&#xff08;LeetCode&#xff09; 1.核心思路&#xff1a;确定循环的路线&#xff0c;左闭右开循环&#xff0c;思路简…