LC每日一题|20240402 - 894. 所有可能的真二叉树
给你一个整数
n,请你找出所有可能含n个节点的 真二叉树 ,并以列表形式返回。答案中每棵树的每个节点都必须符合Node.val == 0。答案的每个元素都是一棵真二叉树的根节点。你可以按 任意顺序 返回最终的真二叉树列表 。
真二叉树 是一类二叉树,树中每个节点恰好有
0或2个子节点。
提示:
1 <= n <= 20
题目级别: Medium
这题已经给了真二叉树的定义,即树中每个节点恰好有 0 或 2 个子节点。
由于每个节点只能有 0 个或者 2 个子节点,所以对于一棵真二叉树,除了其根节点外,任意一层的节点数量一定是偶数个,整个树的节点数量一定是奇数个。此时我们可以对输入数据做一步预处理,即当 n 为偶数时,返回空数组。
同时该树的左子树和右子树一定也满足该性质,显然, n = 当前节点 + 左子树节点数量 + 右子树节点数量,据此我们可以递归求取满足条件的左右子树,并拼接得到需要的结果。而其截止条件即是只有 1 个节点的情况,可以直接返回一个 [0]。
作为优化,我们可以做一个记忆化搜索。但是这个数据范围非常小,所以不做优化也能轻松AC(但是最好还是要写一下的~)。
/**
* Example:
* var ti = TreeNode(5)
* var v = ti.`val`
* Definition for a binary tree node.
* class TreeNode(var `val`: Int) {
* var left: TreeNode? = null
* var right: TreeNode? = null
* }
*/
class Solution {
val map = HashMap<Int, ArrayList<TreeNode>>()
init { map[1] = arrayListOf(TreeNode(0)) }
fun allPossibleFBT(n: Int): List<TreeNode?> {
val res = ArrayList<TreeNode>()
if (n == 1) return map[1]!!
for (i in 1 until n - 1 step 2) {
val j = n - 1 - i
val left = map[i] ?: allPossibleFBT(i)
val right = map[j] ?: allPossibleFBT(j)
for (l in left) {
for (r in right) {
val node = TreeNode(0)
node.left = l
node.right = r
res.add(node)
}
}
}
map[n] = res
return res
}
}