forked from azl397985856/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
lucifer
committed
Jan 20, 2020
1 parent
b88256f
commit 6d4fd99
Showing
3 changed files
with
167 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
## 题目地址(95. 不同的二叉搜索树 II) | ||
|
||
https://leetcode-cn.com/problems/unique-binary-search-trees-ii/description/ | ||
|
||
## 题目描述 | ||
|
||
``` | ||
给定一个整数 n,生成所有由 1 ... n 为节点所组成的二叉搜索树。 | ||
示例: | ||
输入: 3 | ||
输出: | ||
[ | ||
[1,null,3,2], | ||
[3,2,null,1], | ||
[3,1,null,null,2], | ||
[2,1,3], | ||
[1,null,2,null,3] | ||
] | ||
解释: | ||
以上的输出对应以下 5 种不同结构的二叉搜索树: | ||
1 3 3 2 1 | ||
\ / / / \ \ | ||
3 2 1 1 3 2 | ||
/ / \ \ | ||
2 1 2 3 | ||
``` | ||
|
||
## 思路 | ||
|
||
这是一个经典的使用分治思路的题目。基本思路和[96.unique-binary-search-trees](./96.unique-binary-search-trees.md)一样。 | ||
|
||
只是我们需要求解的不仅仅是数字,而是要求解所有的组合。我们假设问题 f(1, n) 是求解 1 到 n(两端包含)的所有二叉树。那么我们的目标就是求解 f(1, n)。 | ||
|
||
我们将问题进一步划分为子问题,假如左侧和右侧的树分别求好了,我们是不是只要运用组合的原理,将左右两者进行做和就好了,我们需要两层循环来完成这个过程。 | ||
|
||
## 关键点解析 | ||
|
||
- 分治法 | ||
|
||
## 代码 | ||
|
||
- 语言支持:Python3 | ||
|
||
Python3 Code: | ||
|
||
```Python | ||
class Solution: | ||
def generateTrees(self, n: int) -> List[TreeNode]: | ||
if not n: | ||
return [] | ||
|
||
def generateTree(start, end): | ||
if start > end: | ||
return [None] | ||
res = [] | ||
for i in range(start, end + 1): | ||
ls = generateTree(start, i - 1) | ||
rs = generateTree(i + 1, end) | ||
for l in ls: | ||
for r in rs: | ||
node = TreeNode(i) | ||
node.left = l | ||
node.right = r | ||
res.append(node) | ||
|
||
return res | ||
|
||
return generateTree(1, n) | ||
``` | ||
|
||
## 相关题目 | ||
|
||
- [96.unique-binary-search-trees](./96.unique-binary-search-trees.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
## 题目地址(96. 不同的二叉搜索树) | ||
|
||
https://leetcode-cn.com/problems/unique-binary-search-trees-ii/description/ | ||
|
||
## 题目描述 | ||
|
||
``` | ||
给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? | ||
示例: | ||
输入: 3 | ||
输出: 5 | ||
解释: | ||
给定 n = 3, 一共有 5 种不同结构的二叉搜索树: | ||
1 3 3 2 1 | ||
\ / / / \ \ | ||
3 2 1 1 3 2 | ||
/ / \ \ | ||
2 1 2 3 | ||
``` | ||
|
||
## 思路 | ||
|
||
这是一个经典的使用分治思路的题目。 | ||
|
||
对于数字 n ,我们可以 1- n 这样的离散整数分成左右两部分。我们不妨设其分别为 A 和 B。那么问题转化为 A 和 B 所能组成的 BST 的数量的笛卡尔积。而对于 A 和 B 以及原问题除了规模,没有不同,这不就是分治思路么?止于此,我们只需要考虑边界即可,边界很简单就是 n 小于等于 1 的时候,我们返回 1。 | ||
|
||
具体来说: | ||
|
||
- 生成一个[1:n + 1] 的数组 | ||
- 我们遍历一次数组,对于每一个数组项,我们执行以下逻辑 | ||
- 对于每一项,我们都假设其是断点。断点左侧的是 A,断点右侧的是 B。 | ||
- 那么 A 就是 i - 1 个数, 那么 B 就是 n - i 个数 | ||
- 我们递归,并将 A 和 B 的结果相乘即可。 | ||
|
||
> 其实我们发现,题目的答案只和 n 有关,和具体 n 个数的具体组成,只要是有序数组即可。 | ||
题目没有明确 n 的取值范围,我们试一下暴力递归。 | ||
|
||
代码(Python3): | ||
|
||
```python | ||
class Solution: | ||
def numTrees(self, n: int) -> int: | ||
if n <= 1: | ||
return 1 | ||
res = 0 | ||
for i in range(1, n + 1): | ||
res += self.numTrees(i - 1) * self.numTrees(n - i) | ||
return res | ||
``` | ||
|
||
上面的代码会超时,并没有栈溢出,因此我们考虑使用 hashmap 来优化,代码见下方代码区。 | ||
|
||
## 关键点解析 | ||
|
||
- 分治法 | ||
- 笛卡尔积 | ||
- 记忆化递归 | ||
|
||
## 代码 | ||
|
||
- 语言支持:Python3 | ||
|
||
Python3 Code: | ||
|
||
```Python | ||
class Solution: | ||
visited = dict() | ||
|
||
def numTrees(self, n: int) -> int: | ||
if n in self.visited: | ||
return self.visited.get(n) | ||
if n <= 1: | ||
return 1 | ||
res = 0 | ||
for i in range(1, n + 1): | ||
res += self.numTrees(i - 1) * self.numTrees(n - i) | ||
self.visited[n] = res | ||
return res | ||
``` |