leetcode题解538:把二叉搜索树转换为累加树

一、题目内容

题目要求将给定的二叉搜索树(BST)转换为累加树(Greater Sum Tree),使每个节点的值等于原树中大于或等于该节点值的所有节点值之和。转换后的树应保持原有的二叉搜索树结构。

二、题目分析

(一)输入和输出

输入:二叉搜索树的根节点 root

输出:转换后的累加树的根节点。

(二)递归函数 convertBST 的逻辑

基本情况:如果当前节点为空(root == NULL),说明当前分支没有节点,直接返回 NULL

递归逻辑:

  1. 从右子树开始递归处理,因为右子树的值大于当前节点的值。

  2. 更新当前节点的值为当前节点值加上之前遍历到的节点值之和(通过一个全局变量 pre 记录)。

  3. 更新全局变量 pre 为当前节点的新值。

  4. 递归地对左子树进行处理。

三、解题要点

(一)二叉搜索树的定义

二叉搜索树是一种特殊的二叉树,其性质是:对于任意节点,其左子树上所有节点的值都小于该节点的值,其右子树上所有节点的值都大于该节点的值。这一性质是转换操作的基础,转换操作需要保持这一性质不变。

(二)转换操作的性质

转换操作需要保持二叉搜索树的结构不变,同时更新每个节点的值为原树中大于或等于该节点值的所有节点值之和。

(三)解题思路

基本情况:

如果当前为空节点(root == NULL),直接返回 NULL。这是递归的终止条件。

递归逻辑:

  1. 从右子树开始递归处理,因为右子树的值大于当前节点的值。

  2. 更新当前节点的值为当前节点值加上之前遍历到的节点值之和。

  3. 更新全局变量 pre 为当前节点的新值。

  4. 递归地对左子树进行处理。

递归返回:

递归返回时,返回当前节点。这一步确保了递归调用的正确性,使得每次递归返回后,当前节点的状态被正确恢复,不会影响后续的递归调用。

四、代码解答

复制代码
class Solution {
public:
    int pre = 0; // 用于记录之前遍历到的节点值之和

    TreeNode* convertBST(TreeNode* root) {
        // 如果当前节点为空,直接返回 NULL
        if (root == NULL) return NULL;

        // 递归地对右子树进行处理
        convertBST(root->right);

        // 更新当前节点的值
        root->val += pre;
        pre = root->val; // 更新全局变量 pre

        // 递归地对左子树进行处理
        convertBST(root->left);

        // 返回当前节点
        return root;
    }
};

五、详细注释

(一)递归函数 convertBST

基本情况:如果当前节点为空,直接返回 NULL

递归逻辑:根据二叉搜索树的性质,从右子树开始递归,更新当前节点的值,然后递归处理左子树。

返回值:返回当前节点,确保递归调用后,当前节点的状态被正确恢复。

(二)全局变量 pre

全局变量 pre 用于记录之前遍历到的节点值之和。它在递归过程中被不断更新,用于计算当前节点的新值。

六、递归和回溯的详细解释

(一)递归

递归是一种函数调用自身的方法,用于解决复杂问题。在本题中,递归用于逐层遍历每个节点,根据二叉搜索树的性质,从右子树开始遍历,更新当前节点的值,并对左子树进行处理。递归的核心思想是将问题分解为更小的子问题,通过解决子问题来解决原问题。

(二)终止条件

递归的终止条件是当前节点为空,此时直接返回 NULL。这是递归的出口,确保递归不会无限进行下去。

(三)回溯

在递归调用返回后,通过返回值恢复到当前节点的状态,确保每次递归返回后,状态正确,不会影响后续的递归调用。

(四)递归调用的详细过程

假设我们有一个二叉搜索树,根节点为 root,值为 5,其左子节点值为 3,右子节点值为 7。现在要将其转换为累加树。

  • 初始调用:convertBST(root),当前节点值为 5

  • 递归调用右子树:convertBST(root->right),当前节点值为 7,更新 pre7

  • 递归调用左子树:convertBST(root->left),当前节点值为 3,更新 pre107 + 3)。

  • 最终返回转换后的根节点,其值为 12,左子树的值为 10,右子树的值为 7

(五)代码执行过程示例

假设我们有一个二叉搜索树,根节点为 root,值为 5,其左子节点值为 3,右子节点值为 7。现在要将其转换为累加树。

  • 初始调用:convertBST(root),当前节点值为 5

  • 递归调用右子树:convertBST(root->right),当前节点值为 7,更新 pre7

  • 递归调用左子树:convertBST(root->left),当前节点值为 3,更新 pre107 + 3)。

  • 最终返回转换后的根节点,其值为 12,左子树的值为 10,右子树的值为 7

通过以上分析和代码实现,我们可以高效地完成二叉搜索树的转换操作,同时保持树的结构和性质不变。

相关推荐
leo__5207 分钟前
matlab实现非线性Granger因果检验
人工智能·算法·matlab
GG不是gg15 分钟前
位运算详解之异或运算的奇妙操作
算法
FF-Studio2 小时前
万物皆数:构建数字信号处理的数学基石
算法·数学建模·fpga开发·自动化·音视频·信号处理·dsp开发
叶子爱分享3 小时前
从事算法工作对算法刷题量的需求
算法
勇闯IT3 小时前
有多少小于当前数字的数字
java·数据结构·算法
liuqun03194 小时前
开心灿烂go开发面试题
算法·leetcode·golang
liulilittle4 小时前
通过高级处理器硬件指令集AES-NI实现AES-256-CFB算法并通过OPENSSL加密验证算法正确性。
linux·服务器·c++·算法·安全·加密·openssl
小皮侠4 小时前
【算法篇】逐步理解动态规划模型6(回文串问题)
java·开发语言·算法·动态规划
IT猿手4 小时前
动态多目标进化算法:基于迁移学习的动态多目标粒子群优化算法(TrMOPSO)求解IEEE CEC 2015,提供完整MATLAB代码
算法·matlab·迁移学习·动态多目标进化优化·动态多目标算法
এ᭄画画的北北4 小时前
力扣-279.完全平方数
数据结构·算法·leetcode