Skip to content

Commit 8fb80ad

Browse files
authored
feat: update solutions to lcci problems: No.04.02~04.04 (doocs#2626)
* No.04.02.Minimum Height Tree * No.04.03.List of Depth * No.04.04.Check Balance
1 parent def45fc commit 8fb80ad

File tree

10 files changed

+85
-123
lines changed

10 files changed

+85
-123
lines changed

lcci/04.02.Minimum Height Tree/README.md

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,15 @@
1111

1212
### 方法一:递归
1313

14-
先找到数组的中间点,作为二叉搜索树的根节点,然后递归左右子树即可
14+
我们设计一个函数 $\text{dfs}(l, r)$,表示构造出从 $l$ 到 $r$ 的子树,那么答案就是 $\text{dfs}(0, \text{len}(nums) - 1)$
1515

16-
时间复杂度 $O(n)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组长度。
16+
函数 $\text{dfs}(l, r)$ 的执行过程如下:
17+
18+
1. 如果 $l > r$,返回 $\text{None}$。
19+
2. 否则,我们计算出中间位置 $mid = \frac{l + r}{2}$,然后构造出根节点,左子树为 $\text{dfs}(l, mid - 1)$,右子树为 $\text{dfs}(mid + 1, r)$。
20+
3. 最后返回根节点。
21+
22+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
1723

1824
<!-- tabs:start -->
1925

@@ -28,7 +34,7 @@
2834

2935
class Solution:
3036
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
31-
def dfs(l, r):
37+
def dfs(l: int, r: int) -> TreeNode:
3238
if l > r:
3339
return None
3440
mid = (l + r) >> 1
@@ -79,7 +85,9 @@ class Solution {
7985
public:
8086
TreeNode* sortedArrayToBST(vector<int>& nums) {
8187
function<TreeNode*(int, int)> dfs = [&](int l, int r) -> TreeNode* {
82-
if (l > r) return nullptr;
88+
if (l > r) {
89+
return nullptr;
90+
}
8391
int mid = l + r >> 1;
8492
return new TreeNode(nums[mid], dfs(l, mid - 1), dfs(mid + 1, r));
8593
};
@@ -160,24 +168,23 @@ function sortedArrayToBST(nums: number[]): TreeNode | null {
160168
use std::rc::Rc;
161169
use std::cell::RefCell;
162170
impl Solution {
163-
fn dfs(nums: &Vec<i32>, start: usize, end: usize) -> Option<Rc<RefCell<TreeNode>>> {
164-
if start >= end {
171+
fn dfs(nums: &Vec<i32>, l: usize, r: usize) -> Option<Rc<RefCell<TreeNode>>> {
172+
if l >= r {
165173
return None;
166174
}
167-
let mid = start + (end - start) / 2;
175+
let mid = (l + r) >> 1;
168176
Some(
169177
Rc::new(
170178
RefCell::new(TreeNode {
171179
val: nums[mid],
172-
left: Self::dfs(nums, start, mid),
173-
right: Self::dfs(nums, mid + 1, end),
180+
left: Self::dfs(nums, l, mid),
181+
right: Self::dfs(nums, mid + 1, r),
174182
})
175183
)
176184
)
177185
}
178186
pub fn sorted_array_to_bst(nums: Vec<i32>) -> Option<Rc<RefCell<TreeNode>>> {
179-
let end = nums.len();
180-
Self::dfs(&nums, 0, end)
187+
Self::dfs(&nums, 0, nums.len())
181188
}
182189
}
183190
```

lcci/04.02.Minimum Height Tree/README_EN.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,17 @@ One possible answer is: [0,-3,9,-10,null,5],which represents the following tre
3232

3333
## Solutions
3434

35-
### Solution 1
35+
### Solution 1: Recursion
36+
37+
We design a function `dfs(l, r)`, which constructs a subtree from `l` to `r`. Therefore, the answer is `dfs(0, len(nums) - 1)`.
38+
39+
The execution process of the function `dfs(l, r)` is as follows:
40+
41+
1. If `l > r`, return `None`.
42+
2. Otherwise, we calculate the middle position `mid = (l + r) / 2`, then construct the root node, the left subtree is `dfs(l, mid - 1)`, and the right subtree is `dfs(mid + 1, r)`.
43+
3. Finally, return the root node.
44+
45+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array.
3646

3747
<!-- tabs:start -->
3848

@@ -47,7 +57,7 @@ One possible answer is: [0,-3,9,-10,null,5],which represents the following tre
4757

4858
class Solution:
4959
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
50-
def dfs(l, r):
60+
def dfs(l: int, r: int) -> TreeNode:
5161
if l > r:
5262
return None
5363
mid = (l + r) >> 1
@@ -98,7 +108,9 @@ class Solution {
98108
public:
99109
TreeNode* sortedArrayToBST(vector<int>& nums) {
100110
function<TreeNode*(int, int)> dfs = [&](int l, int r) -> TreeNode* {
101-
if (l > r) return nullptr;
111+
if (l > r) {
112+
return nullptr;
113+
}
102114
int mid = l + r >> 1;
103115
return new TreeNode(nums[mid], dfs(l, mid - 1), dfs(mid + 1, r));
104116
};
@@ -179,24 +191,23 @@ function sortedArrayToBST(nums: number[]): TreeNode | null {
179191
use std::rc::Rc;
180192
use std::cell::RefCell;
181193
impl Solution {
182-
fn dfs(nums: &Vec<i32>, start: usize, end: usize) -> Option<Rc<RefCell<TreeNode>>> {
183-
if start >= end {
194+
fn dfs(nums: &Vec<i32>, l: usize, r: usize) -> Option<Rc<RefCell<TreeNode>>> {
195+
if l >= r {
184196
return None;
185197
}
186-
let mid = start + (end - start) / 2;
198+
let mid = (l + r) >> 1;
187199
Some(
188200
Rc::new(
189201
RefCell::new(TreeNode {
190202
val: nums[mid],
191-
left: Self::dfs(nums, start, mid),
192-
right: Self::dfs(nums, mid + 1, end),
203+
left: Self::dfs(nums, l, mid),
204+
right: Self::dfs(nums, mid + 1, r),
193205
})
194206
)
195207
)
196208
}
197209
pub fn sorted_array_to_bst(nums: Vec<i32>) -> Option<Rc<RefCell<TreeNode>>> {
198-
let end = nums.len();
199-
Self::dfs(&nums, 0, end)
210+
Self::dfs(&nums, 0, nums.len())
200211
}
201212
}
202213
```

lcci/04.02.Minimum Height Tree/Solution.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ class Solution {
1111
public:
1212
TreeNode* sortedArrayToBST(vector<int>& nums) {
1313
function<TreeNode*(int, int)> dfs = [&](int l, int r) -> TreeNode* {
14-
if (l > r) return nullptr;
14+
if (l > r) {
15+
return nullptr;
16+
}
1517
int mid = l + r >> 1;
1618
return new TreeNode(nums[mid], dfs(l, mid - 1), dfs(mid + 1, r));
1719
};

lcci/04.02.Minimum Height Tree/Solution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class Solution:
1010
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
11-
def dfs(l, r):
11+
def dfs(l: int, r: int) -> TreeNode:
1212
if l > r:
1313
return None
1414
mid = (l + r) >> 1

lcci/04.02.Minimum Height Tree/Solution.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,22 @@
1919
use std::rc::Rc;
2020
use std::cell::RefCell;
2121
impl Solution {
22-
fn dfs(nums: &Vec<i32>, start: usize, end: usize) -> Option<Rc<RefCell<TreeNode>>> {
23-
if start >= end {
22+
fn dfs(nums: &Vec<i32>, l: usize, r: usize) -> Option<Rc<RefCell<TreeNode>>> {
23+
if l >= r {
2424
return None;
2525
}
26-
let mid = start + (end - start) / 2;
26+
let mid = (l + r) >> 1;
2727
Some(
2828
Rc::new(
2929
RefCell::new(TreeNode {
3030
val: nums[mid],
31-
left: Self::dfs(nums, start, mid),
32-
right: Self::dfs(nums, mid + 1, end),
31+
left: Self::dfs(nums, l, mid),
32+
right: Self::dfs(nums, mid + 1, r),
3333
})
3434
)
3535
)
3636
}
3737
pub fn sorted_array_to_bst(nums: Vec<i32>) -> Option<Rc<RefCell<TreeNode>>> {
38-
let end = nums.len();
39-
Self::dfs(&nums, 0, end)
38+
Self::dfs(&nums, 0, nums.len())
4039
}
4140
}

lcci/04.03.List of Depth/README_EN.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@
3838

3939
## Solutions
4040

41-
### Solution 1
41+
### Solution 1: BFS Level Order Traversal
42+
43+
We can use the BFS level order traversal method. For each level, we store the values of the current level's nodes into a list, and then add the list to the result array.
44+
45+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of nodes in the binary tree.
4246

4347
<!-- tabs:start -->
4448

lcci/04.04.Check Balance/README.md

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
函数 $dfs(root)$ 的执行逻辑如下:
1717

1818
- 如果 $root$ 为空,则返回 $0$;
19-
- 否则,我们递归调用 $dfs(root.left)$ 和 $dfs(root.right)$,并判断 $dfs(root.left)$ 和 $dfs(root.right)$ 的返回值是否为 $-1$,如果不为 $-1$,则判断 $abs(dfs(root.left) - dfs(root.right)) <= 1$ 是否成立,如果成立,则返回 $max(dfs(root.left), dfs(root.right)) + 1$,否则返回 $-1$。
19+
- 否则,我们递归调用 $dfs(root.left)$ 和 $dfs(root.right)$,并判断 $dfs(root.left)$ 和 $dfs(root.right)$ 的返回值是否为 $-1$,如果不为 $-1$,则判断 $abs(dfs(root.left) - dfs(root.right)) \leq 1$ 是否成立,如果成立,则返回 $max(dfs(root.left), dfs(root.right)) + 1$,否则返回 $-1$。
2020

2121
在主函数中,我们只需要调用 $dfs(root)$,并判断其返回值是否为 $-1$,如果不为 $-1$,则返回 `true`,否则返回 `false`
2222

@@ -37,12 +37,13 @@ class Solution:
3737
def isBalanced(self, root: TreeNode) -> bool:
3838
def dfs(root: TreeNode):
3939
if root is None:
40-
return 0, True
41-
a, b = dfs(root.left)
42-
c, d = dfs(root.right)
43-
return max(a, c) + 1, abs(a - c) <= 1 and b and d
40+
return 0
41+
l, r = dfs(root.left), dfs(root.right)
42+
if l == -1 or r == -1 or abs(l - r) > 1:
43+
return -1
44+
return max(l, r) + 1
4445

45-
return dfs(root)[1]
46+
return dfs(root) >= 0
4647
```
4748

4849
```java
@@ -168,32 +169,4 @@ function isBalanced(root: TreeNode | null): boolean {
168169

169170
<!-- tabs:end -->
170171

171-
### 方法二
172-
173-
<!-- tabs:start -->
174-
175-
```python
176-
# Definition for a binary tree node.
177-
# class TreeNode:
178-
# def __init__(self, x):
179-
# self.val = x
180-
# self.left = None
181-
# self.right = None
182-
183-
184-
class Solution:
185-
def isBalanced(self, root: TreeNode) -> bool:
186-
def dfs(root: TreeNode):
187-
if root is None:
188-
return 0
189-
l, r = dfs(root.left), dfs(root.right)
190-
if l == -1 or r == -1 or abs(l - r) > 1:
191-
return -1
192-
return max(l, r) + 1
193-
194-
return dfs(root) >= 0
195-
```
196-
197-
<!-- tabs:end -->
198-
199172
<!-- end -->

lcci/04.04.Check Balance/README_EN.md

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,18 @@ return&nbsp;false.</pre>
5252

5353
## Solutions
5454

55-
### Solution 1
55+
### Solution 1: Recursion (Post-order Traversal)
56+
57+
We design a function $dfs(root)$, which returns the height of the tree with $root$ as the root node. If the tree with $root$ as the root node is balanced, it returns the height of the tree, otherwise, it returns $-1$.
58+
59+
The execution logic of the function $dfs(root)$ is as follows:
60+
61+
- If $root$ is null, then return $0$.
62+
- Otherwise, we recursively call $dfs(root.left)$ and $dfs(root.right)$, and check whether the return values of $dfs(root.left)$ and $dfs(root.right)$ are $-1$. If not, we check whether $abs(dfs(root.left) - dfs(root.right)) \leq 1$ holds. If it holds, then return $max(dfs(root.left), dfs(root.right)) + 1$, otherwise return $-1$.
63+
64+
In the main function, we only need to call $dfs(root)$, and check whether its return value is $-1$. If not, return `true`, otherwise return `false`.
65+
66+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of nodes in the binary tree.
5667

5768
<!-- tabs:start -->
5869

@@ -69,12 +80,13 @@ class Solution:
6980
def isBalanced(self, root: TreeNode) -> bool:
7081
def dfs(root: TreeNode):
7182
if root is None:
72-
return 0, True
73-
a, b = dfs(root.left)
74-
c, d = dfs(root.right)
75-
return max(a, c) + 1, abs(a - c) <= 1 and b and d
83+
return 0
84+
l, r = dfs(root.left), dfs(root.right)
85+
if l == -1 or r == -1 or abs(l - r) > 1:
86+
return -1
87+
return max(l, r) + 1
7688

77-
return dfs(root)[1]
89+
return dfs(root) >= 0
7890
```
7991

8092
```java
@@ -200,32 +212,4 @@ function isBalanced(root: TreeNode | null): boolean {
200212

201213
<!-- tabs:end -->
202214

203-
### Solution 2
204-
205-
<!-- tabs:start -->
206-
207-
```python
208-
# Definition for a binary tree node.
209-
# class TreeNode:
210-
# def __init__(self, x):
211-
# self.val = x
212-
# self.left = None
213-
# self.right = None
214-
215-
216-
class Solution:
217-
def isBalanced(self, root: TreeNode) -> bool:
218-
def dfs(root: TreeNode):
219-
if root is None:
220-
return 0
221-
l, r = dfs(root.left), dfs(root.right)
222-
if l == -1 or r == -1 or abs(l - r) > 1:
223-
return -1
224-
return max(l, r) + 1
225-
226-
return dfs(root) >= 0
227-
```
228-
229-
<!-- tabs:end -->
230-
231215
<!-- end -->

lcci/04.04.Check Balance/Solution.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ class Solution:
1010
def isBalanced(self, root: TreeNode) -> bool:
1111
def dfs(root: TreeNode):
1212
if root is None:
13-
return 0, True
14-
a, b = dfs(root.left)
15-
c, d = dfs(root.right)
16-
return max(a, c) + 1, abs(a - c) <= 1 and b and d
13+
return 0
14+
l, r = dfs(root.left), dfs(root.right)
15+
if l == -1 or r == -1 or abs(l - r) > 1:
16+
return -1
17+
return max(l, r) + 1
1718

18-
return dfs(root)[1]
19+
return dfs(root) >= 0

lcci/04.04.Check Balance/Solution2.py

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)