当前位置: 首页 > news >正文

代码随想录阅读笔记-二叉树【二叉搜索树转换为累加树】

题目

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

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

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

示例 1:

538.把二叉搜索树转换为累加树

  • 输入:[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]

示例 3:

  • 输入:root = [1,0,2]
  • 输出:[3,3,2]

示例 4:

  • 输入:root = [3,2,4,1]
  • 输出:[7,9,4,10]

提示:

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

思路

一看到累加树,相信很多小伙伴都会疑惑:如何累加?遇到一个节点,然后再遍历其他节点累加?怎么一想这么麻烦呢。

然后再发现这是一棵二叉搜索树,这是有序的啊。

那么有序的元素如何求累加呢?

其实这就是一棵树,大家可能看起来有点别扭,换一个角度来看,这就是一个有序数组[2, 5, 13],求从后到前的累加数组,也就是[20, 18, 13],是不是感觉这就简单了。

为什么变成数组就是感觉简单了呢?

因为数组大家都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,看起来就别扭了一些是不是。

那么知道如何遍历这个二叉树,也就迎刃而解了,从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了

递归

遍历顺序如图所示:

538.把二叉搜索树转换为累加树

本题依然需要一个pre指针记录当前遍历节点cur的前一个节点,这样才方便做累加。

pre指针的使用技巧,我们在最小绝对差和众数问题中都提到了,这是常用的操作手段。

1、递归函数参数以及返回值

这里很明确了,不需要递归函数的返回值做什么操作了,要遍历整棵树。

同时需要定义一个全局变量pre,用来保存cur节点的前一个节点的数值,定义为int型就可以了。

int pre = 0; // 记录前一个节点的数值
void traversal(TreeNode* cur)

2、确定终止条件

遇空就终止。

if (cur == NULL) return;

3、确定单层递归的逻辑

注意要右中左来遍历二叉树, 中节点的处理逻辑就是让cur的数值加上前一个节点的数值。

traversal(cur->right);  // 右
cur->val += pre;        // 中
pre = cur->val;
traversal(cur->left);   // 左

递归法整体代码如下:

class Solution {
private:int pre = 0; // 记录前一个节点的数值void traversal(TreeNode* cur) { // 右中左遍历if (cur == NULL) return;traversal(cur->right);cur->val += pre;pre = cur->val;traversal(cur->left);}
public:TreeNode* convertBST(TreeNode* root) {pre = 0;traversal(root);return root;}
};
迭代法

迭代法其实就是中序模板题了,这里我给出其中的一种,代码如下:

class Solution {
private:int pre; // 记录前一个节点的数值void traversal(TreeNode* root) {stack<TreeNode*> st;TreeNode* cur = root;while (cur != NULL || !st.empty()) {if (cur != NULL) {st.push(cur);cur = cur->right;   // 右} else {cur = st.top();     // 中st.pop();cur->val += pre;pre = cur->val;cur = cur->left;    // 左}}}
public:TreeNode* convertBST(TreeNode* root) {pre = 0;traversal(root);return root;}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 用vue.js写案例——ToDoList待办事项 (步骤和全码解析)
  • React - 你使用过高阶组件吗
  • WKWebView的使用
  • 安卓远离手机app
  • 自然语言处理-词向量模型-Word2Vec
  • 如何从应用商店Microsoft Store免费下载安装HEVC视频扩展插件
  • 华为OD机试 - 堆栈中的剩余数字(Java JS Python C C++)
  • 【进阶版】基于KubeAdm搭建多节点K8S集群,并使用Rancher导入K8S集群
  • JavaScript中如何理解堆栈溢出和内存泄漏
  • 漫谈:C、C++字符串的困局
  • 【go从入门到精通】作用域,包详解
  • Macos 部署自己的privateGpt(2024-0404)
  • python 08Pandas
  • 想做产品经理,应该选择什么专业?
  • 【汇编】_Visual Studio2019写32位汇编
  • “大数据应用场景”之隔壁老王(连载四)
  • CentOS 7 修改主机名
  • flask接收请求并推入栈
  • java中的hashCode
  • java中具有继承关系的类及其对象初始化顺序
  • October CMS - 快速入门 9 Images And Galleries
  • SAP云平台里Global Account和Sub Account的关系
  • SQLServer之创建数据库快照
  • tweak 支持第三方库
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 那些年我们用过的显示性能指标
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • Nginx实现动静分离
  • 从如何停掉 Promise 链说起
  • ​插件化DPI在商用WIFI中的价值
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #QT(串口助手-界面)
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (1)Jupyter Notebook 下载及安装
  • (4)logging(日志模块)
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (剑指Offer)面试题34:丑数
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (转) Android中ViewStub组件使用
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • (自用)仿写程序
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。