From 131d072526c71be9fdc97ac13f4af77cb13ed748 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Mon, 26 Feb 2024 09:06:29 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.0938 No.0938.Range Sum of BST --- .../0900-0999/0938.Range Sum of BST/README.md | 181 ++++++++++++++---- .../0938.Range Sum of BST/README_EN.md | 181 ++++++++++++++---- .../0938.Range Sum of BST/Solution.cpp | 23 ++- .../0938.Range Sum of BST/Solution.cs | 33 ++++ .../0938.Range Sum of BST/Solution.go | 26 ++- .../0938.Range Sum of BST/Solution.java | 19 +- .../0938.Range Sum of BST/Solution.py | 27 ++- .../0938.Range Sum of BST/Solution.ts | 31 +++ 8 files changed, 400 insertions(+), 121 deletions(-) create mode 100644 solution/0900-0999/0938.Range Sum of BST/Solution.cs create mode 100644 solution/0900-0999/0938.Range Sum of BST/Solution.ts diff --git a/solution/0900-0999/0938.Range Sum of BST/README.md b/solution/0900-0999/0938.Range Sum of BST/README.md index 44178622bb300..680b25a3be00a 100644 --- a/solution/0900-0999/0938.Range Sum of BST/README.md +++ b/solution/0900-0999/0938.Range Sum of BST/README.md @@ -39,7 +39,19 @@ ## 解法 -### 方法一 +### 方法一:DFS + +我们设计一个函数 $dfs(root)$,表示求以 $root$ 为根的子树中,值位于范围 $[low, high]$ 之间的所有结点的值的和。那么答案就是 $dfs(root)$。 + +函数 $dfs(root)$ 的执行逻辑如下: + +- 如果 $root$ 为空,返回 $0$。 +- 如果 $root$ 的值 $x$ 在范围 $[low, high]$ 之间,那么函数 $dfs(root)$ 的初始答案就是 $x$,否则为 $0$。 +- 如果 $x > low$,说明 $root$ 的左子树中可能有值在范围 $[low, high]$ 之间的结点,所以我们需要递归调用 $dfs(root.left)$,并将结果加到答案上。 +- 如果 $x < high$,说明 $root$ 的右子树中可能有值在范围 $[low, high]$ 之间的结点,所以我们需要递归调用 $dfs(root.right)$,并将结果加到答案上。 +- 最后返回答案。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉搜索树的结点个数。 @@ -51,22 +63,19 @@ # self.left = left # self.right = right class Solution: - def rangeSumBST(self, root: TreeNode, low: int, high: int) -> int: - def search(node): - if not node: - return - if low <= node.val <= high: - self.ans += node.val - search(node.left) - search(node.right) - elif node.val < low: - search(node.right) - elif node.val > high: - search(node.left) - - self.ans = 0 - search(root) - return self.ans + def rangeSumBST(self, root: Optional[TreeNode], low: int, high: int) -> int: + def dfs(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + x = root.val + ans = x if low <= x <= high else 0 + if x > low: + ans += dfs(root.left) + if x < high: + ans += dfs(root.right) + return ans + + return dfs(root) ``` ```java @@ -87,17 +96,22 @@ class Solution: */ class Solution { public int rangeSumBST(TreeNode root, int low, int high) { + return dfs(root, low, high); + } + + private int dfs(TreeNode root, int low, int high) { if (root == null) { return 0; } - if (low <= root.val && root.val <= high) { - return root.val + rangeSumBST(root.left, low, high) - + rangeSumBST(root.right, low, high); - } else if (root.val < low) { - return rangeSumBST(root.right, low, high); - } else { - return rangeSumBST(root.left, low, high); + int x = root.val; + int ans = low <= x && x <= high ? x : 0; + if (x > low) { + ans += dfs(root.left, low, high); + } + if (x < high) { + ans += dfs(root.right, low, high); } + return ans; } } ``` @@ -117,14 +131,21 @@ class Solution { class Solution { public: int rangeSumBST(TreeNode* root, int low, int high) { - if (root == nullptr) return 0; - if (low <= root->val && root->val <= high) { - return root->val + rangeSumBST(root->left, low, high) + rangeSumBST(root->right, low, high); - } else if (root->val < low) { - return rangeSumBST(root->right, low, high); - } else { - return rangeSumBST(root->left, low, high); - } + function dfs = [&](TreeNode* root) { + if (!root) { + return 0; + } + int x = root->val; + int ans = low <= x && x <= high ? x : 0; + if (x > low) { + ans += dfs(root->left); + } + if (x < high) { + ans += dfs(root->right); + } + return ans; + }; + return dfs(root); } }; ``` @@ -139,16 +160,94 @@ public: * } */ func rangeSumBST(root *TreeNode, low int, high int) int { - if root == nil { - return 0 - } - if low <= root.Val && root.Val <= high { - return root.Val + rangeSumBST(root.Left, low, high) + rangeSumBST(root.Right, low, high) - } else if root.Val < low { - return rangeSumBST(root.Right, low, high) - } else { - return rangeSumBST(root.Left, low, high) + var dfs func(*TreeNode) int + dfs = func(root *TreeNode) (ans int) { + if root == nil { + return 0 + } + x := root.Val + if low <= x && x <= high { + ans += x + } + if x > low { + ans += dfs(root.Left) + } + if x < high { + ans += dfs(root.Right) + } + return } + return dfs(root) +} +``` + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function rangeSumBST(root: TreeNode | null, low: number, high: number): number { + const dfs = (root: TreeNode | null): number => { + if (!root) { + return 0; + } + const { val, left, right } = root; + let ans = low <= val && val <= high ? val : 0; + if (val > low) { + ans += dfs(left); + } + if (val < high) { + ans += dfs(right); + } + return ans; + }; + return dfs(root); +} +``` + +```cs +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public int RangeSumBST(TreeNode root, int low, int high) { + return dfs(root, low, high); + } + + private int dfs(TreeNode root, int low, int high) { + if (root == null) { + return 0; + } + int x = root.val; + int ans = low <= x && x <= high ? x : 0; + if (x > low) { + ans += dfs(root.left, low, high); + } + if (x < high) { + ans += dfs(root.right, low, high); + } + return ans; + } } ``` diff --git a/solution/0900-0999/0938.Range Sum of BST/README_EN.md b/solution/0900-0999/0938.Range Sum of BST/README_EN.md index 1db354aa730f1..0e7f13e5f5e89 100644 --- a/solution/0900-0999/0938.Range Sum of BST/README_EN.md +++ b/solution/0900-0999/0938.Range Sum of BST/README_EN.md @@ -37,7 +37,19 @@ ## Solutions -### Solution 1 +### Solution 1: DFS + +We design a function $dfs(root)$, which represents the sum of the values of all nodes in the subtree with $root$ as the root, and the values are within the range $[low, high]$. The answer is $dfs(root)$. + +The execution logic of the function $dfs(root)$ is as follows: + +- If $root$ is null, return $0$. +- If the value $x$ of $root$ is within the range $[low, high]$, then the initial answer of the function $dfs(root)$ is $x$, otherwise it is $0$. +- If $x > low$, it means that there may be nodes in the left subtree of $root$ with values within the range $[low, high]$, so we need to recursively call $dfs(root.left)$ and add the result to the answer. +- If $x < high$, it means that there may be nodes in the right subtree of $root$ with values within the range $[low, high]$, so we need to recursively call $dfs(root.right)$ and add the result to the answer. +- Finally, return the answer. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the number of nodes in the binary search tree. @@ -49,22 +61,19 @@ # self.left = left # self.right = right class Solution: - def rangeSumBST(self, root: TreeNode, low: int, high: int) -> int: - def search(node): - if not node: - return - if low <= node.val <= high: - self.ans += node.val - search(node.left) - search(node.right) - elif node.val < low: - search(node.right) - elif node.val > high: - search(node.left) - - self.ans = 0 - search(root) - return self.ans + def rangeSumBST(self, root: Optional[TreeNode], low: int, high: int) -> int: + def dfs(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + x = root.val + ans = x if low <= x <= high else 0 + if x > low: + ans += dfs(root.left) + if x < high: + ans += dfs(root.right) + return ans + + return dfs(root) ``` ```java @@ -85,17 +94,22 @@ class Solution: */ class Solution { public int rangeSumBST(TreeNode root, int low, int high) { + return dfs(root, low, high); + } + + private int dfs(TreeNode root, int low, int high) { if (root == null) { return 0; } - if (low <= root.val && root.val <= high) { - return root.val + rangeSumBST(root.left, low, high) - + rangeSumBST(root.right, low, high); - } else if (root.val < low) { - return rangeSumBST(root.right, low, high); - } else { - return rangeSumBST(root.left, low, high); + int x = root.val; + int ans = low <= x && x <= high ? x : 0; + if (x > low) { + ans += dfs(root.left, low, high); } + if (x < high) { + ans += dfs(root.right, low, high); + } + return ans; } } ``` @@ -115,14 +129,21 @@ class Solution { class Solution { public: int rangeSumBST(TreeNode* root, int low, int high) { - if (root == nullptr) return 0; - if (low <= root->val && root->val <= high) { - return root->val + rangeSumBST(root->left, low, high) + rangeSumBST(root->right, low, high); - } else if (root->val < low) { - return rangeSumBST(root->right, low, high); - } else { - return rangeSumBST(root->left, low, high); - } + function dfs = [&](TreeNode* root) { + if (!root) { + return 0; + } + int x = root->val; + int ans = low <= x && x <= high ? x : 0; + if (x > low) { + ans += dfs(root->left); + } + if (x < high) { + ans += dfs(root->right); + } + return ans; + }; + return dfs(root); } }; ``` @@ -137,16 +158,94 @@ public: * } */ func rangeSumBST(root *TreeNode, low int, high int) int { - if root == nil { - return 0 - } - if low <= root.Val && root.Val <= high { - return root.Val + rangeSumBST(root.Left, low, high) + rangeSumBST(root.Right, low, high) - } else if root.Val < low { - return rangeSumBST(root.Right, low, high) - } else { - return rangeSumBST(root.Left, low, high) + var dfs func(*TreeNode) int + dfs = func(root *TreeNode) (ans int) { + if root == nil { + return 0 + } + x := root.Val + if low <= x && x <= high { + ans += x + } + if x > low { + ans += dfs(root.Left) + } + if x < high { + ans += dfs(root.Right) + } + return } + return dfs(root) +} +``` + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function rangeSumBST(root: TreeNode | null, low: number, high: number): number { + const dfs = (root: TreeNode | null): number => { + if (!root) { + return 0; + } + const { val, left, right } = root; + let ans = low <= val && val <= high ? val : 0; + if (val > low) { + ans += dfs(left); + } + if (val < high) { + ans += dfs(right); + } + return ans; + }; + return dfs(root); +} +``` + +```cs +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public int RangeSumBST(TreeNode root, int low, int high) { + return dfs(root, low, high); + } + + private int dfs(TreeNode root, int low, int high) { + if (root == null) { + return 0; + } + int x = root.val; + int ans = low <= x && x <= high ? x : 0; + if (x > low) { + ans += dfs(root.left, low, high); + } + if (x < high) { + ans += dfs(root.right, low, high); + } + return ans; + } } ``` diff --git a/solution/0900-0999/0938.Range Sum of BST/Solution.cpp b/solution/0900-0999/0938.Range Sum of BST/Solution.cpp index 60b263bb8e5d0..fa24c212b7860 100644 --- a/solution/0900-0999/0938.Range Sum of BST/Solution.cpp +++ b/solution/0900-0999/0938.Range Sum of BST/Solution.cpp @@ -12,13 +12,20 @@ class Solution { public: int rangeSumBST(TreeNode* root, int low, int high) { - if (root == nullptr) return 0; - if (low <= root->val && root->val <= high) { - return root->val + rangeSumBST(root->left, low, high) + rangeSumBST(root->right, low, high); - } else if (root->val < low) { - return rangeSumBST(root->right, low, high); - } else { - return rangeSumBST(root->left, low, high); - } + function dfs = [&](TreeNode* root) { + if (!root) { + return 0; + } + int x = root->val; + int ans = low <= x && x <= high ? x : 0; + if (x > low) { + ans += dfs(root->left); + } + if (x < high) { + ans += dfs(root->right); + } + return ans; + }; + return dfs(root); } }; \ No newline at end of file diff --git a/solution/0900-0999/0938.Range Sum of BST/Solution.cs b/solution/0900-0999/0938.Range Sum of BST/Solution.cs new file mode 100644 index 0000000000000..1da5701f3e717 --- /dev/null +++ b/solution/0900-0999/0938.Range Sum of BST/Solution.cs @@ -0,0 +1,33 @@ +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public int RangeSumBST(TreeNode root, int low, int high) { + return dfs(root, low, high); + } + + private int dfs(TreeNode root, int low, int high) { + if (root == null) { + return 0; + } + int x = root.val; + int ans = low <= x && x <= high ? x : 0; + if (x > low) { + ans += dfs(root.left, low, high); + } + if (x < high) { + ans += dfs(root.right, low, high); + } + return ans; + } +} \ No newline at end of file diff --git a/solution/0900-0999/0938.Range Sum of BST/Solution.go b/solution/0900-0999/0938.Range Sum of BST/Solution.go index 80c3ed0ffa839..28d9732897775 100644 --- a/solution/0900-0999/0938.Range Sum of BST/Solution.go +++ b/solution/0900-0999/0938.Range Sum of BST/Solution.go @@ -7,14 +7,22 @@ * } */ func rangeSumBST(root *TreeNode, low int, high int) int { - if root == nil { - return 0 - } - if low <= root.Val && root.Val <= high { - return root.Val + rangeSumBST(root.Left, low, high) + rangeSumBST(root.Right, low, high) - } else if root.Val < low { - return rangeSumBST(root.Right, low, high) - } else { - return rangeSumBST(root.Left, low, high) + var dfs func(*TreeNode) int + dfs = func(root *TreeNode) (ans int) { + if root == nil { + return 0 + } + x := root.Val + if low <= x && x <= high { + ans += x + } + if x > low { + ans += dfs(root.Left) + } + if x < high { + ans += dfs(root.Right) + } + return } + return dfs(root) } \ No newline at end of file diff --git a/solution/0900-0999/0938.Range Sum of BST/Solution.java b/solution/0900-0999/0938.Range Sum of BST/Solution.java index d28179e4448cb..dba4a75eeb75f 100644 --- a/solution/0900-0999/0938.Range Sum of BST/Solution.java +++ b/solution/0900-0999/0938.Range Sum of BST/Solution.java @@ -15,16 +15,21 @@ */ class Solution { public int rangeSumBST(TreeNode root, int low, int high) { + return dfs(root, low, high); + } + + private int dfs(TreeNode root, int low, int high) { if (root == null) { return 0; } - if (low <= root.val && root.val <= high) { - return root.val + rangeSumBST(root.left, low, high) - + rangeSumBST(root.right, low, high); - } else if (root.val < low) { - return rangeSumBST(root.right, low, high); - } else { - return rangeSumBST(root.left, low, high); + int x = root.val; + int ans = low <= x && x <= high ? x : 0; + if (x > low) { + ans += dfs(root.left, low, high); + } + if (x < high) { + ans += dfs(root.right, low, high); } + return ans; } } \ No newline at end of file diff --git a/solution/0900-0999/0938.Range Sum of BST/Solution.py b/solution/0900-0999/0938.Range Sum of BST/Solution.py index cc3f0259e9260..e4a8af3589226 100644 --- a/solution/0900-0999/0938.Range Sum of BST/Solution.py +++ b/solution/0900-0999/0938.Range Sum of BST/Solution.py @@ -5,19 +5,16 @@ # self.left = left # self.right = right class Solution: - def rangeSumBST(self, root: TreeNode, low: int, high: int) -> int: - def search(node): - if not node: - return - if low <= node.val <= high: - self.ans += node.val - search(node.left) - search(node.right) - elif node.val < low: - search(node.right) - elif node.val > high: - search(node.left) + def rangeSumBST(self, root: Optional[TreeNode], low: int, high: int) -> int: + def dfs(root: Optional[TreeNode]) -> int: + if root is None: + return 0 + x = root.val + ans = x if low <= x <= high else 0 + if x > low: + ans += dfs(root.left) + if x < high: + ans += dfs(root.right) + return ans - self.ans = 0 - search(root) - return self.ans + return dfs(root) diff --git a/solution/0900-0999/0938.Range Sum of BST/Solution.ts b/solution/0900-0999/0938.Range Sum of BST/Solution.ts new file mode 100644 index 0000000000000..b0403fbc6228e --- /dev/null +++ b/solution/0900-0999/0938.Range Sum of BST/Solution.ts @@ -0,0 +1,31 @@ +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function rangeSumBST(root: TreeNode | null, low: number, high: number): number { + const dfs = (root: TreeNode | null): number => { + if (!root) { + return 0; + } + const { val, left, right } = root; + let ans = low <= val && val <= high ? val : 0; + if (val > low) { + ans += dfs(left); + } + if (val < high) { + ans += dfs(right); + } + return ans; + }; + return dfs(root); +}