力扣日记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为新值。对示例图中的二叉树也是一样,通过一个值来累积遍历到的节点值,每遍历到一个节点,就加上这个累积值(实际上也是上一个遍历到的节点的新值)作为新节点值即可
  • 所以通过一个递归函数,右中左来进行逆向中序遍历,并用一个全局变量来记录累积值
  • 不要用传递参数或者返回值来记录累积值!!!会相当麻烦,直接用全局变量即可!!!(其实就是一个指向上一个节点的指针
相关推荐
想跑步的小弱鸡2 分钟前
Leetcode hot 100(day 4)
算法·leetcode·职场和发展
Fantasydg3 分钟前
DAY 35 leetcode 202--哈希表.快乐数
算法·leetcode·散列表
jyyyx的算法博客4 分钟前
Leetcode 2337 -- 双指针 | 脑筋急转弯
算法·leetcode
SweetCode15 分钟前
裴蜀定理:整数解的奥秘
数据结构·python·线性代数·算法·机器学习
ゞ 正在缓冲99%…28 分钟前
leetcode76.最小覆盖子串
java·算法·leetcode·字符串·双指针·滑动窗口
xuanjiong29 分钟前
纯个人整理,蓝桥杯使用的算法模板day2(0-1背包问题),手打个人理解注释,超全面,且均已验证成功(附带详细手写“模拟流程图”,全网首个
算法·蓝桥杯·动态规划
惊鸿.Jh1 小时前
【滑动窗口】3254. 长度为 K 的子数组的能量值 I
数据结构·算法·leetcode
明灯L1 小时前
《函数基础与内存机制深度剖析:从 return 语句到各类经典编程题详解》
经验分享·python·算法·链表·经典例题
碳基学AI1 小时前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义免费下载方法
大数据·人工智能·python·gpt·算法·语言模型·集成学习
补三补四1 小时前
机器学习-聚类分析算法
人工智能·深度学习·算法·机器学习