力扣日记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为新值。对示例图中的二叉树也是一样,通过一个值来累积遍历到的节点值,每遍历到一个节点,就加上这个累积值(实际上也是上一个遍历到的节点的新值)作为新节点值即可。
  • 所以通过一个递归函数,右中左来进行逆向中序遍历,并用一个全局变量来记录累积值
  • 不要用传递参数或者返回值来记录累积值!!!会相当麻烦,直接用全局变量即可!!!(其实就是一个指向上一个节点的指针)
相关推荐
ZhengEnCi8 小时前
Agent 架构怎么选:从单 Agent 到多 Agent 编排的选型决策指南
算法·架构
秋天的怀念_David9 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Pniubi9 小时前
力扣283移动零(双指针法)
算法·leetcode·职场和发展
hhb_6189 小时前
大模型落地三重优化实战
人工智能·算法·机器学习
云和数据.ChenGuang10 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
2601_9707038311 小时前
工业除湿机租赁:把一份租金合同拆开看
大数据·数据结构·算法·数据库架构·推荐算法
心中有你021411 小时前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
ZhengEnCi12 小时前
同样的模型,为什么本地和云 API 差别那么大:量化精度、聊天模板与采样参数的三大元凶
人工智能·算法·llm
Flynn Liang12 小时前
RAG 答非所问/幻觉怎么破?Spring AI QuestionAnswerAdvisor 召回优化实战(TopK/重排/混合检索)
人工智能·算法·spring·rag·幻觉·springai
liminla!13 小时前
SQL 从入门到进阶:语法速查与实战练习(完整优化版)
数据库·sql·算法