95. 不同的二叉搜索树 II
- 题目
- 算法设计:深度优先搜索
传送门:https://leetcode.cn/problems/unique-binary-search-trees-ii/
二叉树子问题分解 = 根节点 + 左右子树的子问题。
根节点的子问题:循环历遍每一个元素,以这个元素作为根节点。
左子树的子问题:左子树的所有可行的集合。
右子树的子问题:右子树的所有可行的集合。
分析过程:
[1, n]
是一个单调递增序列。i
作为根节点,那比它小的元素 [1, i-1]
就只能是属于它的左子树,比它大的节点 [i+1, n]
只能是属于它的右子树。{1,2}
的组合,右子树就是 {4,5}
的组合。3
为根节点的二叉搜索树数量 = 左子树的所有可行的集合 * 右子树的所有可行的集合。n
的所有二叉搜索树数量 = 以 1
为根节点的二叉搜索树数量 + 以 2
为根节点的二叉搜索树数量 + 以 3
为根节点的二叉搜索树数量 + 以 4
为根节点的二叉搜索树数量 + 以 5
为根节点的二叉搜索树数量class Solution {
public:vector dfs(int start, int end) {vector res;if (start > end) return {NULL}; // 空树for (int i = start; i <= end; i++) { // 枚举每个 i 为根节点vector left = dfs(start, i-1), right = dfs(i+1, end); // 以i作为根节点,那比它小的元素[1, i-1]就只能是它的左子树,比它大的节点[i+1, n]只能是它的右子树。再递归调用,得出所有可行的左子树和可行的右子树。for (auto l : left) // 从可行左子树集合中选一棵for (auto r : right) // 从可行右子树集合中选一棵res.push_back(new TreeNode(i, l, r)); // 并拼接到根节点i上,把生成的子树序列放入答案数组}return res; // 再由子树的解推出原问题的解}vector generateTrees(int n) {vector res = dfs(1, n);return res;}
};
递归代码为什么可以这么写的推导:
https://leetcode.cn/problems/unique-binary-search-trees-ii/solution/cong-gou-jian-dan-ke-shu-dao-gou-jian-suo-you-shu-/
上一篇:知识图谱简介
下一篇:Oracle数据库入门大全