From d429e49515701f723f7861168e2f19b0edbe154e Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 6 Dec 2024 09:36:45 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.1005 --- .../README.md | 14 +- .../README_EN.md | 18 +- .../Solution.ts | 6 +- .../README.md | 190 +++++++++--------- .../README_EN.md | 190 +++++++++--------- .../Solution.cpp | 38 ++-- .../Solution.go | 18 +- .../Solution.java | 24 ++- .../Solution.py | 30 ++- .../Solution.rs | 45 ++--- .../Solution.ts | 31 +-- 11 files changed, 297 insertions(+), 307 deletions(-) diff --git a/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README.md b/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README.md index 271e19bc69d63..79f57d5ded5ab 100644 --- a/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README.md +++ b/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README.md @@ -76,13 +76,13 @@ tags: 我们观察发现,要使得数组的和尽可能大,就应该尽可能地将数组中的最小负数变成正数。 -而题目中元素的范围为 $[-100,100]$,因此,我们可以先用哈希表 $cnt$ 统计数组 $nums$ 中每个元素出现的次数。接着从 $-100$ 开始遍历 $x$,如果哈希表中存在 $x$,那么我们取 $m = \min(cnt[x], k)$ 作为元素 $x$ 取反的个数,然后我们将 $cnt[x]$ 减去 $m$,将 $cnt[-x]$ 加上 $m$,并将 $k$ 减去 $m$。如果 $k$ 为 $0$,说明操作已经结束,直接退出循环即可。 +而题目中元素的范围为 $[-100,100]$,因此,我们可以先用哈希表 $\textit{cnt}$ 统计数组 $\textit{nums}$ 中每个元素出现的次数。接着从 $-100$ 开始遍历 $x$,如果哈希表中存在 $x$,那么我们取 $m = \min(cnt[x], k)$ 作为元素 $x$ 取反的个数,然后我们将 $\textit{cnt}[x]$ 减去 $m$,将 $\textit{cnt}[-x]$ 加上 $m$,并将 $k$ 减去 $m$。如果 $k$ 为 $0$,说明操作已经结束,直接退出循环即可。 -如果 $k$ 仍然为奇数,且 $cnt[0]=0$,那么我们还需要取 $cnt$ 中最小的一个正数 $x$,将 $cnt[x]$ 减去 $1$,将 $cnt[-x]$ 加上 $1$。 +如果 $k$ 仍然为奇数,且 $\textit{cnt}[0]=0$,那么我们还需要取 $\textit{cnt}$ 中最小的一个正数 $x$,将 $\textit{cnt}[x]$ 减去 $1$,将 $\textit{cnt}[-x]$ 加上 $1$。 -最后,我们遍历哈希表 $cnt$,将 $x$ 与 $cnt[x]$ 相乘的结果累加,即为答案。 +最后,我们遍历哈希表 $\textit{cnt}$,将 $x$ 与 $\textit{cnt}[x]$ 相乘的结果累加,即为答案。 -时间复杂度 $O(n + M)$,空间复杂度 $O(M)$。其中 $n$ 和 $M$ 分别为数组 $nums$ 的长度和 $nums$ 的数据范围大小。 +时间复杂度 $O(n + M)$,空间复杂度 $O(M)$。其中 $n$ 和 $M$ 分别为数组 $\textit{nums}$ 的长度和 $\textit{nums}$ 的数据范围大小。 @@ -237,11 +237,7 @@ function largestSumAfterKNegations(nums: number[], k: number): number { } } } - let ans = 0; - for (const [key, value] of cnt.entries()) { - ans += key * value; - } - return ans; + return Array.from(cnt.entries()).reduce((acc, [k, v]) => acc + k * v, 0); } ``` diff --git a/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README_EN.md b/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README_EN.md index 6597e0690bc4c..c9c608c86ca3e 100644 --- a/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README_EN.md +++ b/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/README_EN.md @@ -70,7 +70,17 @@ tags: -### Solution 1 +### Solution 1: Greedy + Counting + +We observe that to maximize the sum of the array, we should try to turn the smallest negative numbers into positive numbers. + +Given that the range of elements is $[-100, 100]$, we can use a hash table $\textit{cnt}$ to count the occurrences of each element in the array $\textit{nums}$. Then, starting from $-100$, we iterate through $x$. If $x$ exists in the hash table, we take $m = \min(\textit{cnt}[x], k)$ as the number of times to negate the element $x$. We then subtract $m$ from $\textit{cnt}[x]$, add $m$ to $\textit{cnt}[-x]$, and subtract $m$ from $k$. If $k$ becomes $0$, the operation is complete, and we exit the loop. + +If $k$ is still odd and $\textit{cnt}[0] = 0$, we need to take the smallest positive number $x$ in $\textit{cnt}$, subtract $1$ from $\textit{cnt}[x]$, and add $1$ to $\textit{cnt}[-x]$. + +Finally, we traverse the hash table $\textit{cnt}$ and sum the products of $x$ and $\textit{cnt}[x]$ to get the answer. + +The time complexity is $O(n + M)$, and the space complexity is $O(M)$. Here, $n$ and $M$ are the length of the array $\textit{nums}$ and the size of the data range of $\textit{nums}$, respectively. @@ -225,11 +235,7 @@ function largestSumAfterKNegations(nums: number[], k: number): number { } } } - let ans = 0; - for (const [key, value] of cnt.entries()) { - ans += key * value; - } - return ans; + return Array.from(cnt.entries()).reduce((acc, [k, v]) => acc + k * v, 0); } ``` diff --git a/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/Solution.ts b/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/Solution.ts index 98ac83f664b51..e4f3845d1f05e 100644 --- a/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/Solution.ts +++ b/solution/1000-1099/1005.Maximize Sum Of Array After K Negations/Solution.ts @@ -20,9 +20,5 @@ function largestSumAfterKNegations(nums: number[], k: number): number { } } } - let ans = 0; - for (const [key, value] of cnt.entries()) { - ans += key * value; - } - return ans; + return Array.from(cnt.entries()).reduce((acc, [k, v]) => acc + k * v, 0); } diff --git a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/README.md b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/README.md index ea6d2588f15b3..8078632c3ee3b 100644 --- a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/README.md +++ b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/README.md @@ -67,37 +67,39 @@ tags: -### 方法一 +### 方法一:DFS + 二分查找 + +我们设计一个函数 $\textit{dfs}(i, j)$,表示构造出从 $\textit{preorder}[i]$ 到 $\textit{preorder}[j]$ 这些节点构成的二叉搜索树。那么答案就是 $\textit{dfs}(0, n - 1)$。 + +在 $\textit{dfs}(i, j)$ 中,我们首先构造根节点,即 $\textit{preorder}[i]$。然后使用二分查找的方法找到第一个大于 $\textit{preorder}[i]$ 的节点的下标 $\textit{mid}$,将 $\textit{dfs}(i + 1, \textit{mid} - 1)$ 作为根节点的左子树,将 $\textit{dfs}(\textit{mid}, j)$ 作为根节点的右子树。 + +最后返回根节点即可。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{preorder}$ 的长度。 #### Python3 ```python -# Definition for a binary tree node. -# class TreeNode: -# def __init__(self, val=0, left=None, right=None): -# self.val = val -# self.left = left -# self.right = right class Solution: def bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]: - def dfs(preorder): - if not preorder: + def dfs(i: int, j: int) -> Optional[TreeNode]: + if i > j: return None - root = TreeNode(preorder[0]) - left, right = 1, len(preorder) - while left < right: - mid = (left + right) >> 1 - if preorder[mid] > preorder[0]: - right = mid + root = TreeNode(preorder[i]) + l, r = i + 1, j + 1 + while l < r: + mid = (l + r) >> 1 + if preorder[mid] > preorder[i]: + r = mid else: - left = mid + 1 - root.left = dfs(preorder[1:left]) - root.right = dfs(preorder[left:]) + l = mid + 1 + root.left = dfs(i + 1, l - 1) + root.right = dfs(l, j) return root - return dfs(preorder) + return dfs(0, len(preorder) - 1) ``` #### Java @@ -119,27 +121,29 @@ class Solution: * } */ class Solution { + private int[] preorder; public TreeNode bstFromPreorder(int[] preorder) { - return dfs(preorder, 0, preorder.length - 1); + this.preorder = preorder; + return dfs(0, preorder.length - 1); } - private TreeNode dfs(int[] preorder, int i, int j) { - if (i > j || i >= preorder.length) { + private TreeNode dfs(int i, int j) { + if (i > j) { return null; } TreeNode root = new TreeNode(preorder[i]); - int left = i + 1, right = j + 1; - while (left < right) { - int mid = (left + right) >> 1; + int l = i + 1, r = j + 1; + while (l < r) { + int mid = (l + r) >> 1; if (preorder[mid] > preorder[i]) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - root.left = dfs(preorder, i + 1, left - 1); - root.right = dfs(preorder, left, j); + root.left = dfs(i + 1, l - 1); + root.right = dfs(l, j); return root; } } @@ -162,23 +166,25 @@ class Solution { class Solution { public: TreeNode* bstFromPreorder(vector& preorder) { - return dfs(preorder, 0, preorder.size() - 1); - } - - TreeNode* dfs(vector& preorder, int i, int j) { - if (i > j || i >= preorder.size()) return nullptr; - TreeNode* root = new TreeNode(preorder[i]); - int left = i + 1, right = j + 1; - while (left < right) { - int mid = (left + right) >> 1; - if (preorder[mid] > preorder[i]) - right = mid; - else - left = mid + 1; - } - root->left = dfs(preorder, i + 1, left - 1); - root->right = dfs(preorder, left, j); - return root; + auto dfs = [&](auto&& dfs, int i, int j) -> TreeNode* { + if (i > j) { + return nullptr; + } + TreeNode* root = new TreeNode(preorder[i]); + int l = i + 1, r = j + 1; + while (l < r) { + int mid = (l + r) >> 1; + if (preorder[mid] > preorder[i]) { + r = mid; + } else { + l = mid + 1; + } + } + root->left = dfs(dfs, i + 1, l - 1); + root->right = dfs(dfs, l, j); + return root; + }; + return dfs(dfs, 0, preorder.size() - 1); } }; ``` @@ -197,21 +203,21 @@ public: func bstFromPreorder(preorder []int) *TreeNode { var dfs func(i, j int) *TreeNode dfs = func(i, j int) *TreeNode { - if i > j || i >= len(preorder) { + if i > j { return nil } root := &TreeNode{Val: preorder[i]} - left, right := i+1, len(preorder) - for left < right { - mid := (left + right) >> 1 + l, r := i+1, j+1 + for l < r { + mid := (l + r) >> 1 if preorder[mid] > preorder[i] { - right = mid + r = mid } else { - left = mid + 1 + l = mid + 1 } } - root.Left = dfs(i+1, left-1) - root.Right = dfs(left, j) + root.Left = dfs(i+1, l-1) + root.Right = dfs(l, j) return root } return dfs(0, len(preorder)-1) @@ -236,24 +242,25 @@ func bstFromPreorder(preorder []int) *TreeNode { */ function bstFromPreorder(preorder: number[]): TreeNode | null { - const n = preorder.length; - const next = new Array(n); - const stack = []; - for (let i = n - 1; i >= 0; i--) { - while (stack.length !== 0 && preorder[stack[stack.length - 1]] < preorder[i]) { - stack.pop(); - } - next[i] = stack[stack.length - 1] ?? n; - stack.push(i); - } - - const dfs = (left: number, right: number) => { - if (left >= right) { + const dfs = (i: number, j: number): TreeNode | null => { + if (i > j) { return null; } - return new TreeNode(preorder[left], dfs(left + 1, next[left]), dfs(next[left], right)); + const root = new TreeNode(preorder[i]); + let [l, r] = [i + 1, j + 1]; + while (l < r) { + const mid = (l + r) >> 1; + if (preorder[mid] > preorder[i]) { + r = mid; + } else { + l = mid + 1; + } + } + root.left = dfs(i + 1, l - 1); + root.right = dfs(l, j); + return root; }; - return dfs(0, n); + return dfs(0, preorder.length - 1); } ``` @@ -281,36 +288,29 @@ function bstFromPreorder(preorder: number[]): TreeNode | null { use std::cell::RefCell; use std::rc::Rc; impl Solution { - fn dfs( - preorder: &Vec, - next: &Vec, - left: usize, - right: usize, - ) -> Option>> { - if left >= right { - return None; - } - Some(Rc::new(RefCell::new(TreeNode { - val: preorder[left], - left: Self::dfs(preorder, next, left + 1, next[left]), - right: Self::dfs(preorder, next, next[left], right), - }))) - } - pub fn bst_from_preorder(preorder: Vec) -> Option>> { - let n = preorder.len(); - let mut stack = Vec::new(); - let mut next = vec![n; n]; - for i in (0..n).rev() { - while !stack.is_empty() && preorder[*stack.last().unwrap()] < preorder[i] { - stack.pop(); + fn dfs(preorder: &Vec, i: usize, j: usize) -> Option>> { + if i > j { + return None; } - if !stack.is_empty() { - next[i] = *stack.last().unwrap(); + let root = Rc::new(RefCell::new(TreeNode::new(preorder[i]))); + let mut l = i + 1; + let mut r = j + 1; + while l < r { + let mid = (l + r) >> 1; + if preorder[mid] > preorder[i] { + r = mid; + } else { + l = mid + 1; + } } - stack.push(i); + let mut root_ref = root.borrow_mut(); + root_ref.left = dfs(preorder, i + 1, l - 1); + root_ref.right = dfs(preorder, l, j); + Some(root.clone()) } - Self::dfs(&preorder, &next, 0, n) + + dfs(&preorder, 0, preorder.len() - 1) } } ``` diff --git a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/README_EN.md b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/README_EN.md index 62b5c8d41fed2..9bf02ca4fbe11 100644 --- a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/README_EN.md +++ b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/README_EN.md @@ -61,37 +61,39 @@ tags: -### Solution 1 +### Solution 1: DFS + Binary Search + +We design a function $\textit{dfs}(i, j)$ to construct a binary search tree from the nodes $\textit{preorder}[i]$ to $\textit{preorder}[j]$. The answer is $\textit{dfs}(0, n - 1)$. + +In $\textit{dfs}(i, j)$, we first construct the root node, which is $\textit{preorder}[i]$. Then, we use binary search to find the first node greater than $\textit{preorder}[i]$ and get its index $\textit{mid}$. We set $\textit{dfs}(i + 1, \textit{mid} - 1)$ as the left subtree of the root node and $\textit{dfs}(\textit{mid}, j)$ as the right subtree of the root node. + +Finally, we return the root node. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $\textit{preorder}$. #### Python3 ```python -# Definition for a binary tree node. -# class TreeNode: -# def __init__(self, val=0, left=None, right=None): -# self.val = val -# self.left = left -# self.right = right class Solution: def bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]: - def dfs(preorder): - if not preorder: + def dfs(i: int, j: int) -> Optional[TreeNode]: + if i > j: return None - root = TreeNode(preorder[0]) - left, right = 1, len(preorder) - while left < right: - mid = (left + right) >> 1 - if preorder[mid] > preorder[0]: - right = mid + root = TreeNode(preorder[i]) + l, r = i + 1, j + 1 + while l < r: + mid = (l + r) >> 1 + if preorder[mid] > preorder[i]: + r = mid else: - left = mid + 1 - root.left = dfs(preorder[1:left]) - root.right = dfs(preorder[left:]) + l = mid + 1 + root.left = dfs(i + 1, l - 1) + root.right = dfs(l, j) return root - return dfs(preorder) + return dfs(0, len(preorder) - 1) ``` #### Java @@ -113,27 +115,29 @@ class Solution: * } */ class Solution { + private int[] preorder; public TreeNode bstFromPreorder(int[] preorder) { - return dfs(preorder, 0, preorder.length - 1); + this.preorder = preorder; + return dfs(0, preorder.length - 1); } - private TreeNode dfs(int[] preorder, int i, int j) { - if (i > j || i >= preorder.length) { + private TreeNode dfs(int i, int j) { + if (i > j) { return null; } TreeNode root = new TreeNode(preorder[i]); - int left = i + 1, right = j + 1; - while (left < right) { - int mid = (left + right) >> 1; + int l = i + 1, r = j + 1; + while (l < r) { + int mid = (l + r) >> 1; if (preorder[mid] > preorder[i]) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - root.left = dfs(preorder, i + 1, left - 1); - root.right = dfs(preorder, left, j); + root.left = dfs(i + 1, l - 1); + root.right = dfs(l, j); return root; } } @@ -156,23 +160,25 @@ class Solution { class Solution { public: TreeNode* bstFromPreorder(vector& preorder) { - return dfs(preorder, 0, preorder.size() - 1); - } - - TreeNode* dfs(vector& preorder, int i, int j) { - if (i > j || i >= preorder.size()) return nullptr; - TreeNode* root = new TreeNode(preorder[i]); - int left = i + 1, right = j + 1; - while (left < right) { - int mid = (left + right) >> 1; - if (preorder[mid] > preorder[i]) - right = mid; - else - left = mid + 1; - } - root->left = dfs(preorder, i + 1, left - 1); - root->right = dfs(preorder, left, j); - return root; + auto dfs = [&](auto&& dfs, int i, int j) -> TreeNode* { + if (i > j) { + return nullptr; + } + TreeNode* root = new TreeNode(preorder[i]); + int l = i + 1, r = j + 1; + while (l < r) { + int mid = (l + r) >> 1; + if (preorder[mid] > preorder[i]) { + r = mid; + } else { + l = mid + 1; + } + } + root->left = dfs(dfs, i + 1, l - 1); + root->right = dfs(dfs, l, j); + return root; + }; + return dfs(dfs, 0, preorder.size() - 1); } }; ``` @@ -191,21 +197,21 @@ public: func bstFromPreorder(preorder []int) *TreeNode { var dfs func(i, j int) *TreeNode dfs = func(i, j int) *TreeNode { - if i > j || i >= len(preorder) { + if i > j { return nil } root := &TreeNode{Val: preorder[i]} - left, right := i+1, len(preorder) - for left < right { - mid := (left + right) >> 1 + l, r := i+1, j+1 + for l < r { + mid := (l + r) >> 1 if preorder[mid] > preorder[i] { - right = mid + r = mid } else { - left = mid + 1 + l = mid + 1 } } - root.Left = dfs(i+1, left-1) - root.Right = dfs(left, j) + root.Left = dfs(i+1, l-1) + root.Right = dfs(l, j) return root } return dfs(0, len(preorder)-1) @@ -230,24 +236,25 @@ func bstFromPreorder(preorder []int) *TreeNode { */ function bstFromPreorder(preorder: number[]): TreeNode | null { - const n = preorder.length; - const next = new Array(n); - const stack = []; - for (let i = n - 1; i >= 0; i--) { - while (stack.length !== 0 && preorder[stack[stack.length - 1]] < preorder[i]) { - stack.pop(); - } - next[i] = stack[stack.length - 1] ?? n; - stack.push(i); - } - - const dfs = (left: number, right: number) => { - if (left >= right) { + const dfs = (i: number, j: number): TreeNode | null => { + if (i > j) { return null; } - return new TreeNode(preorder[left], dfs(left + 1, next[left]), dfs(next[left], right)); + const root = new TreeNode(preorder[i]); + let [l, r] = [i + 1, j + 1]; + while (l < r) { + const mid = (l + r) >> 1; + if (preorder[mid] > preorder[i]) { + r = mid; + } else { + l = mid + 1; + } + } + root.left = dfs(i + 1, l - 1); + root.right = dfs(l, j); + return root; }; - return dfs(0, n); + return dfs(0, preorder.length - 1); } ``` @@ -275,36 +282,29 @@ function bstFromPreorder(preorder: number[]): TreeNode | null { use std::cell::RefCell; use std::rc::Rc; impl Solution { - fn dfs( - preorder: &Vec, - next: &Vec, - left: usize, - right: usize, - ) -> Option>> { - if left >= right { - return None; - } - Some(Rc::new(RefCell::new(TreeNode { - val: preorder[left], - left: Self::dfs(preorder, next, left + 1, next[left]), - right: Self::dfs(preorder, next, next[left], right), - }))) - } - pub fn bst_from_preorder(preorder: Vec) -> Option>> { - let n = preorder.len(); - let mut stack = Vec::new(); - let mut next = vec![n; n]; - for i in (0..n).rev() { - while !stack.is_empty() && preorder[*stack.last().unwrap()] < preorder[i] { - stack.pop(); + fn dfs(preorder: &Vec, i: usize, j: usize) -> Option>> { + if i > j { + return None; } - if !stack.is_empty() { - next[i] = *stack.last().unwrap(); + let root = Rc::new(RefCell::new(TreeNode::new(preorder[i]))); + let mut l = i + 1; + let mut r = j + 1; + while l < r { + let mid = (l + r) >> 1; + if preorder[mid] > preorder[i] { + r = mid; + } else { + l = mid + 1; + } } - stack.push(i); + let mut root_ref = root.borrow_mut(); + root_ref.left = dfs(preorder, i + 1, l - 1); + root_ref.right = dfs(preorder, l, j); + Some(root.clone()) } - Self::dfs(&preorder, &next, 0, n) + + dfs(&preorder, 0, preorder.len() - 1) } } ``` diff --git a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.cpp b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.cpp index 5e03ec536d15d..dc898630b99c0 100644 --- a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.cpp +++ b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.cpp @@ -12,22 +12,24 @@ class Solution { public: TreeNode* bstFromPreorder(vector& preorder) { - return dfs(preorder, 0, preorder.size() - 1); + auto dfs = [&](auto&& dfs, int i, int j) -> TreeNode* { + if (i > j) { + return nullptr; + } + TreeNode* root = new TreeNode(preorder[i]); + int l = i + 1, r = j + 1; + while (l < r) { + int mid = (l + r) >> 1; + if (preorder[mid] > preorder[i]) { + r = mid; + } else { + l = mid + 1; + } + } + root->left = dfs(dfs, i + 1, l - 1); + root->right = dfs(dfs, l, j); + return root; + }; + return dfs(dfs, 0, preorder.size() - 1); } - - TreeNode* dfs(vector& preorder, int i, int j) { - if (i > j || i >= preorder.size()) return nullptr; - TreeNode* root = new TreeNode(preorder[i]); - int left = i + 1, right = j + 1; - while (left < right) { - int mid = (left + right) >> 1; - if (preorder[mid] > preorder[i]) - right = mid; - else - left = mid + 1; - } - root->left = dfs(preorder, i + 1, left - 1); - root->right = dfs(preorder, left, j); - return root; - } -}; \ No newline at end of file +}; diff --git a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.go b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.go index a885bc9ac7c62..c13c70679c3e0 100644 --- a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.go +++ b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.go @@ -9,22 +9,22 @@ func bstFromPreorder(preorder []int) *TreeNode { var dfs func(i, j int) *TreeNode dfs = func(i, j int) *TreeNode { - if i > j || i >= len(preorder) { + if i > j { return nil } root := &TreeNode{Val: preorder[i]} - left, right := i+1, len(preorder) - for left < right { - mid := (left + right) >> 1 + l, r := i+1, j+1 + for l < r { + mid := (l + r) >> 1 if preorder[mid] > preorder[i] { - right = mid + r = mid } else { - left = mid + 1 + l = mid + 1 } } - root.Left = dfs(i+1, left-1) - root.Right = dfs(left, j) + root.Left = dfs(i+1, l-1) + root.Right = dfs(l, j) return root } return dfs(0, len(preorder)-1) -} \ No newline at end of file +} diff --git a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.java b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.java index 05ca64f7aa651..e03004796be3c 100644 --- a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.java +++ b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.java @@ -14,27 +14,29 @@ * } */ class Solution { + private int[] preorder; public TreeNode bstFromPreorder(int[] preorder) { - return dfs(preorder, 0, preorder.length - 1); + this.preorder = preorder; + return dfs(0, preorder.length - 1); } - private TreeNode dfs(int[] preorder, int i, int j) { - if (i > j || i >= preorder.length) { + private TreeNode dfs(int i, int j) { + if (i > j) { return null; } TreeNode root = new TreeNode(preorder[i]); - int left = i + 1, right = j + 1; - while (left < right) { - int mid = (left + right) >> 1; + int l = i + 1, r = j + 1; + while (l < r) { + int mid = (l + r) >> 1; if (preorder[mid] > preorder[i]) { - right = mid; + r = mid; } else { - left = mid + 1; + l = mid + 1; } } - root.left = dfs(preorder, i + 1, left - 1); - root.right = dfs(preorder, left, j); + root.left = dfs(i + 1, l - 1); + root.right = dfs(l, j); return root; } -} \ No newline at end of file +} diff --git a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.py b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.py index 539497cb5daa0..23fcac5a81e56 100644 --- a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.py +++ b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.py @@ -1,24 +1,18 @@ -# Definition for a binary tree node. -# class TreeNode: -# def __init__(self, val=0, left=None, right=None): -# self.val = val -# self.left = left -# self.right = right class Solution: def bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]: - def dfs(preorder): - if not preorder: + def dfs(i: int, j: int) -> Optional[TreeNode]: + if i > j: return None - root = TreeNode(preorder[0]) - left, right = 1, len(preorder) - while left < right: - mid = (left + right) >> 1 - if preorder[mid] > preorder[0]: - right = mid + root = TreeNode(preorder[i]) + l, r = i + 1, j + 1 + while l < r: + mid = (l + r) >> 1 + if preorder[mid] > preorder[i]: + r = mid else: - left = mid + 1 - root.left = dfs(preorder[1:left]) - root.right = dfs(preorder[left:]) + l = mid + 1 + root.left = dfs(i + 1, l - 1) + root.right = dfs(l, j) return root - return dfs(preorder) + return dfs(0, len(preorder) - 1) diff --git a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.rs b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.rs index dbbf9ef5afb39..a39745574d948 100644 --- a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.rs +++ b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.rs @@ -19,35 +19,28 @@ use std::cell::RefCell; use std::rc::Rc; impl Solution { - fn dfs( - preorder: &Vec, - next: &Vec, - left: usize, - right: usize, - ) -> Option>> { - if left >= right { - return None; - } - Some(Rc::new(RefCell::new(TreeNode { - val: preorder[left], - left: Self::dfs(preorder, next, left + 1, next[left]), - right: Self::dfs(preorder, next, next[left], right), - }))) - } - pub fn bst_from_preorder(preorder: Vec) -> Option>> { - let n = preorder.len(); - let mut stack = Vec::new(); - let mut next = vec![n; n]; - for i in (0..n).rev() { - while !stack.is_empty() && preorder[*stack.last().unwrap()] < preorder[i] { - stack.pop(); + fn dfs(preorder: &Vec, i: usize, j: usize) -> Option>> { + if i > j { + return None; } - if !stack.is_empty() { - next[i] = *stack.last().unwrap(); + let root = Rc::new(RefCell::new(TreeNode::new(preorder[i]))); + let mut l = i + 1; + let mut r = j + 1; + while l < r { + let mid = (l + r) >> 1; + if preorder[mid] > preorder[i] { + r = mid; + } else { + l = mid + 1; + } } - stack.push(i); + let mut root_ref = root.borrow_mut(); + root_ref.left = dfs(preorder, i + 1, l - 1); + root_ref.right = dfs(preorder, l, j); + Some(root.clone()) } - Self::dfs(&preorder, &next, 0, n) + + dfs(&preorder, 0, preorder.len() - 1) } } diff --git a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.ts b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.ts index 21de8908a1b16..aa70d99e19d82 100644 --- a/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.ts +++ b/solution/1000-1099/1008.Construct Binary Search Tree from Preorder Traversal/Solution.ts @@ -13,22 +13,23 @@ */ function bstFromPreorder(preorder: number[]): TreeNode | null { - const n = preorder.length; - const next = new Array(n); - const stack = []; - for (let i = n - 1; i >= 0; i--) { - while (stack.length !== 0 && preorder[stack[stack.length - 1]] < preorder[i]) { - stack.pop(); - } - next[i] = stack[stack.length - 1] ?? n; - stack.push(i); - } - - const dfs = (left: number, right: number) => { - if (left >= right) { + const dfs = (i: number, j: number): TreeNode | null => { + if (i > j) { return null; } - return new TreeNode(preorder[left], dfs(left + 1, next[left]), dfs(next[left], right)); + const root = new TreeNode(preorder[i]); + let [l, r] = [i + 1, j + 1]; + while (l < r) { + const mid = (l + r) >> 1; + if (preorder[mid] > preorder[i]) { + r = mid; + } else { + l = mid + 1; + } + } + root.left = dfs(i + 1, l - 1); + root.right = dfs(l, j); + return root; }; - return dfs(0, n); + return dfs(0, preorder.length - 1); }