力扣日记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为新值。对示例图中的二叉树也是一样,通过一个值来累积遍历到的节点值,每遍历到一个节点,就加上这个累积值(实际上也是上一个遍历到的节点的新值)作为新节点值即可
  • 所以通过一个递归函数,右中左来进行逆向中序遍历,并用一个全局变量来记录累积值
  • 不要用传递参数或者返回值来记录累积值!!!会相当麻烦,直接用全局变量即可!!!(其实就是一个指向上一个节点的指针
相关推荐
wabs6663 小时前
关于图论【卡码网117.软件构建的思考】
数据结构·算法·软件构建·图论·卡码网
mifengxing4 小时前
LeetCode 41.缺失的第一个正数|Hard题O(n)+O(1)最优解法深度解析
java·算法·leetcode·排序算法
Tongzhi20264 小时前
从部署到运维:通芝科技无感考勤一体机的全流程效率解析
运维·数据结构·科技·算法·贪心算法
Wang's Blog4 小时前
AI Agent白手起家30: 动态示例选择器之根据长度选择 Few Shot 示例
算法
oyguyteggytrrwwwrt6 小时前
自制交叉线路识别算法
算法
手写码匠6 小时前
华为云Flexus+DeepSeek征文|Dify 多智能体协同编排实战:R1 规划 + V3 执行,构建企业 Agent 团队
人工智能·深度学习·算法·aigc
城管不管7 小时前
第六次面试2026.8.5北京一面已OC
面试·职场和发展
晓天衡宇•评测社区7 小时前
FSR-Bench 前沿科学推理榜单发布:GPT-5.5 居首,“会推理”未必“能答对”
算法
程序喵大人8 小时前
【C++进阶】STL算法与函数对象 - 02 sort为什么需要随机访问迭代器
开发语言·c++·算法
hanlin038 小时前
动态规划专练:力扣第121、122题
笔记·算法·leetcode