力扣日记1.19-【二叉树篇】538. 把二叉搜索树转换为累加树

力扣日记:【二叉树篇】538. 把二叉搜索树转换为累加树

日期:2023.1.19

参考:代码随想录、力扣

ps:因为准备组会汇报又搁置了好久(其实就是懒+逃避T^T),但这是最后一道二叉树啦啊啊啊!!!

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

题目描述

难度:

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

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

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。
    注意:本题和 第1038题 相同

示例 1:

输入: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 和 10^4 之间。
  • 每个节点的值介于 -10^4 和 10^4 之间。
  • 树中的所有值 互不相同 。
  • 给定的树为二叉搜索树。

题解

cpp 复制代码
/**
 * 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) {
        traversal(root);    // 遍历完后,每个节点的新值都更新了
        return root;
    }
    // 思路:按照 右中左 的顺序遍历,节点的值加上当前累积值即为新的节点值
    // 并将当前累加值更新为新节点值,相当于累积值边遍历边累加
    int val = 0;    // 记录当前累加值(全局变量,每遍历一个值,会加上现在遍历到的值)
    void traversal(TreeNode* root) {
        // 右中左(逆序)
        if (root == nullptr) return;
        // 右
        traversal(root->right); // 向右递归遍历
        // 中
        root->val += val;   // 当前值加上累积值
        val = root->val;    // 更新累积值(相当于原累积值加上了当前值)
        // 左
        traversal(root->left);  // 向左递归遍历
    }

};

复杂度

时间复杂度:

空间复杂度:

思路总结

  • 思路:按照 右中左 的顺序遍历,节点的值加上当前累积值即为新的节点值,同时将当前累加值更新为新节点值(相当于累积值边遍历边累加)
  • 这个思路是我瞅着示例图模拟老半天才得出的结论(悲),对此,代码随想录提供了一个很好的思路------"(二叉搜索树root = 5,2,13)换一个角度来看,就是一个有序数组2, 5, 13,求从后到前的累加数组,也就是20, 18, 13,是不是感觉这就简单了 ",也就是说对该二叉搜索树进行逆向中序遍历(右左中),先遍历到13(13+0=13),再遍历到5,5+13=18为新值,再遍历到2,2+18=20为新值。对示例图中的二叉树也是一样,通过一个值来累积遍历到的节点值,每遍历到一个节点,就加上这个累积值(实际上也是上一个遍历到的节点的新值)作为新节点值即可
  • 所以通过一个递归函数,右中左来进行逆向中序遍历,并用一个全局变量来记录累积值
  • 不要用传递参数或者返回值来记录累积值!!!会相当麻烦,直接用全局变量即可!!!(其实就是一个指向上一个节点的指针
相关推荐
DeepAgent14 分钟前
AI Agent 面试篇(01):AI 岗位面试到底怎么走——从网申到 Offer 的完整流程
人工智能·面试·职场和发展
CodeRecycle25 分钟前
Python 自动配置 pip 支持库(通过 Windows Bat 脚本)
算法
liliangcsdn42 分钟前
特质偏度因子的计算示例和分析
算法
荆棘鸟智能1 小时前
无人机遥感图像实时拼接算法工程实践:从特征提取到全景融合的完整技术链路
算法·无人机
6Hzlia2 小时前
【Classic 150 刷题计划】 LeetCode 58. 最后一个单词的长度 | C++ 极简反向遍历与单变量状态机
算法
AgentMaster2 小时前
企业如何应用智能客服?5 个典型场景的技术架构与实施路径
大数据·算法
程曦曦2 小时前
MySQL 生产库误删 98 张表后的时间点恢复实战:从 binlog 解析到资金对账
linux·数据结构·其他·算法·ubuntu·运维开发
weixin_307779133 小时前
C++代码实现MATLAB中的ode45函数功能
开发语言·c++·算法·matlab
不穿鞋的懒羊羊3 小时前
dfs深度优先搜索
算法
OYYHXPJR4 小时前
【算法】区间重叠模板和矩形重叠模板
算法