【树】894. 所有可能的满二叉树

题目:

满二叉树是一类二叉树,其中每个结点恰好有 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]]

 

 解答:

递归+记忆化

根节点的左子树和右子树仍是满二叉树。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    //记忆化,用于后续求FBT(i),其中i<N
    Map<Integer,List<TreeNode>> map = new HashMap<>();

    public List<TreeNode> allPossibleFBT(int N) {

        if(!map.containsKey(N)){
            List<TreeNode> res = new ArrayList<>();
            if(N == 1){
                res.add(new TreeNode(0));
            }

            //满二叉树都是奇数个节点
            if(N%2!=0){
                //根据这里满二叉树的定义,根的左子树和右子树分别都是满二叉树
                //设左子树的节点个数为x,则右子树的个数应该为N-x-1
                //左子树和右子树的每个笛卡尔积就能构成一个新的N个节点的满二叉树
                for(int x = 0;x<N;x++){
                    int y = N-x-1;
                    for(TreeNode left:allPossibleFBT(x))
                        for(TreeNode right:allPossibleFBT(y)){
                            TreeNode node = new TreeNode(0);
                            node.left = left;
                            node.right = right;
                            res.add(node);
                        }
                }
            }
            //对于偶数个节点,直接在map中插入一个空的List
            map.put(N,res);
        }
        return map.get(N);
    }

}

 

posted @ 2020-10-12 00:01  3KBLACK  阅读(109)  评论(0)    收藏  举报