题目描述
满二叉树是一类二叉树,其中每个结点恰好有 0 或 2 个子结点。
返回包含 N 个结点的所有可能满二叉树的列表。 答案的每个元素都是一个可能树的根结点。
答案中每个树的每个结点都必须有 node.val=0。
你可以按任何顺序返回树的最终列表。
示例:
输入:7
输出:[[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,null,null,null,null,0,0],[0,0,0,0,0,null,null,0,0]]
解释:
Sample Code
可以不判断 N % 2 == 0的情况,因为就算不判断,在后面for(TreeNode lr : le) 和 for(TreeNode rr : ri) 的地方会跳过,不过时间复杂度会增加
class Solution {
public List<TreeNode> allPossibleFBT(int N) {
List<TreeNode> res = new ArrayList<>();
if(N % 2 == 0) return res;
if(N == 1) {
TreeNode node = new TreeNode(0);
res.add(node);
return res;
}
for(int i = 1; i < N; i+=2) {
List<TreeNode> le = allPossibleFBT(i);
List<TreeNode> ri = allPossibleFBT(N-1-i);
for(TreeNode lr : le) {
for(TreeNode rr : ri) {
TreeNode node = new TreeNode(0);
node.left = lr;
node.right = rr;
res.add(node);
}
}
}
return res;
}
}
Sample Code(优化)
因为每次递归调用都要重新构造相同的满子树,所以可以用记忆化回溯的思想,
不过因此需要判断 N % 2 == 0
class Solution {
List<List<TreeNode>> memo = new ArrayList<>();
public List<TreeNode> allPossibleFBT(int N) {
List<TreeNode> res = new ArrayList<>();
if(N % 2 == 0) return res;
if(memo.size() > N / 2) return memo.get(N/2);
if(N == 1) {
TreeNode node = new TreeNode(0);
res.add(node);
memo.add(res);
return res;
}
for(int i = 1; i < N; i+=2) {
List<TreeNode> le = allPossibleFBT(i);
List<TreeNode> ri = allPossibleFBT(N-1-i);
for(TreeNode lr : le) {
for(TreeNode rr : ri) {
TreeNode node = new TreeNode(0);
node.left = lr;
node.right = rr;
res.add(node);
}
}
}
memo.add(res);
return res;
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/all-possible-full-binary-trees