diff --git a/include/s0538_convert_bst_to_greater_tree.hpp b/include/s0538_convert_bst_to_greater_tree.hpp new file mode 100644 index 0000000..aa1b04b --- /dev/null +++ b/include/s0538_convert_bst_to_greater_tree.hpp @@ -0,0 +1,13 @@ +#ifndef S0538_CONVERT_BST_TO_GREATER_TREE_HPP +#define S0538_CONVERT_BST_TO_GREATER_TREE_HPP + +#include "structures.hpp" + +class S0538 { + public: + int sum{0}; + TreeNode* convertBST1(TreeNode* root); + TreeNode* convertBST2(TreeNode* root); +}; + +#endif diff --git a/notes/src/bstree.md b/notes/src/bstree.md index 546fb4d..8c2294b 100644 --- a/notes/src/bstree.md +++ b/notes/src/bstree.md @@ -5,3 +5,4 @@ - [s0450](https://leetcode.cn/problems/delete-node-in-a-bst/description/): 删除节点。递归删除。 - [s0669](https://leetcode.cn/problems/trim-a-binary-search-tree/description/): 修剪 BST 。递归修剪。 - [s0108](https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/): 有序数组转 BST 。数组中点为根节点,中点左侧部分生成左子树,右侧部分生成右子树,递归。 +- [s0538](https://leetcode.cn/problems/convert-bst-to-greater-tree/description/): BST 转累加树。可以找到每个节点的构建方法然后用直观一点的递归方式来写,不过本题有个特殊之处在于累加树的生成方式正好和反序中序遍历的遍历路径相同,因此可以用反序中序遍历来遍历生成。 diff --git a/src/s0538_convert_bst_to_greater_tree.cpp b/src/s0538_convert_bst_to_greater_tree.cpp new file mode 100644 index 0000000..701d413 --- /dev/null +++ b/src/s0538_convert_bst_to_greater_tree.cpp @@ -0,0 +1,47 @@ +#include "s0538_convert_bst_to_greater_tree.hpp" + +// 思路一:直观递归 +TreeNode* S0538::convertBST1(TreeNode* root) { + // 为空则直接返回 + if (root == nullptr) return nullptr; + + // 更新右子树 + root->right = convertBST1(root->right); + + // 更新根节点的值 + if (root->right != nullptr) { + // 找到右子树的最左侧节点 + TreeNode* node = root->right; + while (node->left != nullptr) node = node->left; + // 根节点 = 根节点 + 右子树的最左侧节点 + root->val += node->val; + } + + // 接下来处理左子树 + if (root->left != nullptr) { + // 先把根节点的值加到左子树的最右侧点 + TreeNode* node = root->left; + // 找到左子树的最右侧点 + while (node->right != nullptr) node = node->right; + // 加上去 + node->val += root->val; + // 更新左子树 + root->left = convertBST1(root->left); + } + + // 返回 + return root; +} + +// 思路二:反序中序遍历 +// 反序中序遍历的遍历路径正好和累加树的路径相同,因此可以直接用它来遍历 +// 用一个全局变量 sum 记录遍历过程中每个节点的值 +TreeNode* S0538::convertBST2(TreeNode* root) { + if (root != nullptr) { + convertBST2(root->right); + sum += root->val; + root->val = sum; + convertBST2(root->left); + } + return root; +}