From acfacab61a9a29342797e940347d85092ba11050 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 29 Mar 2025 17:08:54 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.1038 --- .../README.md | 70 +++++++------- .../README_EN.md | 91 +++++++++++-------- .../Solution.cpp | 20 ++-- .../Solution.py | 6 +- .../Solution.rs | 24 ++--- .../Solution.ts | 18 ++-- 6 files changed, 126 insertions(+), 103 deletions(-) diff --git a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/README.md b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/README.md index 51d5dd2846f39..fa007bee123f2 100644 --- a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/README.md +++ b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/README.md @@ -87,12 +87,12 @@ tags: # self.left = left # self.right = right class Solution: - def bstToGst(self, root: TreeNode) -> TreeNode: - def dfs(root): - nonlocal s + def bstToGst(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + def dfs(root: Optional[TreeNode]): if root is None: return dfs(root.right) + nonlocal s s += root.val root.val = s dfs(root.left) @@ -156,20 +156,20 @@ class Solution { */ class Solution { public: - int s = 0; - TreeNode* bstToGst(TreeNode* root) { + int s = 0; + auto dfs = [&](this auto&& dfs, TreeNode* root) { + if (!root) { + return; + } + dfs(root->right); + s += root->val; + root->val = s; + dfs(root->left); + }; dfs(root); return root; } - - void dfs(TreeNode* root) { - if (!root) return; - dfs(root->right); - s += root->val; - root->val = s; - dfs(root->left); - } }; ``` @@ -219,17 +219,17 @@ func bstToGst(root *TreeNode) *TreeNode { */ function bstToGst(root: TreeNode | null): TreeNode | null { - const dfs = (root: TreeNode | null, sum: number) => { - if (root == null) { - return sum; + let s = 0; + const dfs = (root: TreeNode | null) => { + if (!root) { + return; } - const { val, left, right } = root; - sum = dfs(right, sum) + val; - root.val = sum; - sum = dfs(left, sum); - return sum; + dfs(root.right); + s += root.val; + root.val = s; + dfs(root.left); }; - dfs(root, 0); + dfs(root); return root; } ``` @@ -255,22 +255,24 @@ function bstToGst(root: TreeNode | null): TreeNode | null { // } // } // } -use std::cell::RefCell; use std::rc::Rc; +use std::cell::RefCell; + impl Solution { - fn dfs(root: &mut Option>>, mut sum: i32) -> i32 { - if let Some(node) = root { - let mut node = node.as_ref().borrow_mut(); - sum = Self::dfs(&mut node.right, sum) + node.val; - node.val = sum; - sum = Self::dfs(&mut node.left, sum); - } - sum + pub fn bst_to_gst(root: Option>>) -> Option>> { + let mut s = 0; + Self::dfs(&root, &mut s); + root } - pub fn bst_to_gst(mut root: Option>>) -> Option>> { - Self::dfs(&mut root, 0); - root + fn dfs(root: &Option>>, s: &mut i32) { + if let Some(node) = root { + let mut node = node.borrow_mut(); + Self::dfs(&node.right, s); + *s += node.val; + node.val = *s; + Self::dfs(&node.left, s); + } } } ``` diff --git a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/README_EN.md b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/README_EN.md index f0b0a6a082837..97d3ea002dab7 100644 --- a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/README_EN.md +++ b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/README_EN.md @@ -64,7 +64,11 @@ tags: -### Solution 1 +### Solution 1: Recursion + +Traverse the binary search tree in the order of "right-root-left". Accumulate all the node values encountered into $s$, and assign the accumulated value to the corresponding `node`. + +Time complexity is $O(n)$, and space complexity is $O(n)$, where $n$ is the number of nodes in the binary search tree. @@ -78,12 +82,12 @@ tags: # self.left = left # self.right = right class Solution: - def bstToGst(self, root: TreeNode) -> TreeNode: - def dfs(root): - nonlocal s + def bstToGst(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + def dfs(root: Optional[TreeNode]): if root is None: return dfs(root.right) + nonlocal s s += root.val root.val = s dfs(root.left) @@ -147,20 +151,20 @@ class Solution { */ class Solution { public: - int s = 0; - TreeNode* bstToGst(TreeNode* root) { + int s = 0; + auto dfs = [&](this auto&& dfs, TreeNode* root) { + if (!root) { + return; + } + dfs(root->right); + s += root->val; + root->val = s; + dfs(root->left); + }; dfs(root); return root; } - - void dfs(TreeNode* root) { - if (!root) return; - dfs(root->right); - s += root->val; - root->val = s; - dfs(root->left); - } }; ``` @@ -210,17 +214,17 @@ func bstToGst(root *TreeNode) *TreeNode { */ function bstToGst(root: TreeNode | null): TreeNode | null { - const dfs = (root: TreeNode | null, sum: number) => { - if (root == null) { - return sum; + let s = 0; + const dfs = (root: TreeNode | null) => { + if (!root) { + return; } - const { val, left, right } = root; - sum = dfs(right, sum) + val; - root.val = sum; - sum = dfs(left, sum); - return sum; + dfs(root.right); + s += root.val; + root.val = s; + dfs(root.left); }; - dfs(root, 0); + dfs(root); return root; } ``` @@ -246,22 +250,24 @@ function bstToGst(root: TreeNode | null): TreeNode | null { // } // } // } -use std::cell::RefCell; use std::rc::Rc; +use std::cell::RefCell; + impl Solution { - fn dfs(root: &mut Option>>, mut sum: i32) -> i32 { - if let Some(node) = root { - let mut node = node.as_ref().borrow_mut(); - sum = Self::dfs(&mut node.right, sum) + node.val; - node.val = sum; - sum = Self::dfs(&mut node.left, sum); - } - sum + pub fn bst_to_gst(root: Option>>) -> Option>> { + let mut s = 0; + Self::dfs(&root, &mut s); + root } - pub fn bst_to_gst(mut root: Option>>) -> Option>> { - Self::dfs(&mut root, 0); - root + fn dfs(root: &Option>>, s: &mut i32) { + if let Some(node) = root { + let mut node = node.borrow_mut(); + Self::dfs(&node.right, s); + *s += node.val; + node.val = *s; + Self::dfs(&node.left, s); + } } } ``` @@ -330,7 +336,20 @@ struct TreeNode* bstToGst(struct TreeNode* root) { -### Solution 2 +### Solution 2: Morris Traversal + +Morris traversal does not require a stack, with a time complexity of $O(n)$ and a space complexity of $O(1)$. The core idea is as follows: + +Define $s$ as the cumulative sum of the node values in the binary search tree. Traverse the binary tree nodes: + +1. If the right subtree of the current node `root` is null, **add the current node value to $s$**, update the current node value to $s$, and move the current node to `root.left`. +2. If the right subtree of the current node `root` is not null, find the leftmost node `next` in the right subtree (i.e., the successor node of `root` in an in-order traversal): + - If the left subtree of the successor node `next` is null, set the left subtree of `next` to point to the current node `root`, and move the current node to `root.right`. + - If the left subtree of the successor node `next` is not null, **add the current node value to $s$**, update the current node value to $s$, then set the left subtree of `next` to null (i.e., remove the link between `next` and `root`), and move the current node to `root.left`. +3. Repeat the above steps until the binary tree nodes are null, at which point the traversal is complete. +4. Finally, return the root node of the binary search tree. + +> Morris reverse in-order traversal follows the same idea as Morris in-order traversal, except that the traversal order changes from "left-root-right" to "right-root-left". diff --git a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.cpp b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.cpp index e3f8ad1c493cf..325fdd44c7aea 100644 --- a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.cpp +++ b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.cpp @@ -11,18 +11,18 @@ */ class Solution { public: - int s = 0; - TreeNode* bstToGst(TreeNode* root) { + int s = 0; + auto dfs = [&](this auto&& dfs, TreeNode* root) { + if (!root) { + return; + } + dfs(root->right); + s += root->val; + root->val = s; + dfs(root->left); + }; dfs(root); return root; } - - void dfs(TreeNode* root) { - if (!root) return; - dfs(root->right); - s += root->val; - root->val = s; - dfs(root->left); - } }; \ No newline at end of file diff --git a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.py b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.py index db01d320edb78..d03ef87bb5eee 100644 --- a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.py +++ b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.py @@ -5,12 +5,12 @@ # self.left = left # self.right = right class Solution: - def bstToGst(self, root: TreeNode) -> TreeNode: - def dfs(root): - nonlocal s + def bstToGst(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + def dfs(root: Optional[TreeNode]): if root is None: return dfs(root.right) + nonlocal s s += root.val root.val = s dfs(root.left) diff --git a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.rs b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.rs index f2b6b87562fe8..55ab171abbfbc 100644 --- a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.rs +++ b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.rs @@ -18,19 +18,21 @@ // } use std::cell::RefCell; use std::rc::Rc; + impl Solution { - fn dfs(root: &mut Option>>, mut sum: i32) -> i32 { - if let Some(node) = root { - let mut node = node.as_ref().borrow_mut(); - sum = Self::dfs(&mut node.right, sum) + node.val; - node.val = sum; - sum = Self::dfs(&mut node.left, sum); - } - sum + pub fn bst_to_gst(root: Option>>) -> Option>> { + let mut s = 0; + Self::dfs(&root, &mut s); + root } - pub fn bst_to_gst(mut root: Option>>) -> Option>> { - Self::dfs(&mut root, 0); - root + fn dfs(root: &Option>>, s: &mut i32) { + if let Some(node) = root { + let mut node = node.borrow_mut(); + Self::dfs(&node.right, s); + *s += node.val; + node.val = *s; + Self::dfs(&node.left, s); + } } } diff --git a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.ts b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.ts index 2f90397898b6c..f2346fdc247d0 100644 --- a/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.ts +++ b/solution/1000-1099/1038.Binary Search Tree to Greater Sum Tree/Solution.ts @@ -13,16 +13,16 @@ */ function bstToGst(root: TreeNode | null): TreeNode | null { - const dfs = (root: TreeNode | null, sum: number) => { - if (root == null) { - return sum; + let s = 0; + const dfs = (root: TreeNode | null) => { + if (!root) { + return; } - const { val, left, right } = root; - sum = dfs(right, sum) + val; - root.val = sum; - sum = dfs(left, sum); - return sum; + dfs(root.right); + s += root.val; + root.val = s; + dfs(root.left); }; - dfs(root, 0); + dfs(root); return root; }