LeetCode 894. All Possible Full Binary Trees (记忆搜索)

Description:
A full binary tree is a binary tree where each node has exactly 0 or 2 children.

Return a list of all possible full binary trees with N nodes. Each element of the answer is the root node of one possible tree.

Each node of each tree in the answer must have node.val = 0.

You may return the final list of trees in any order.

Example 1:
在这里插入图片描述
Note:

1 <= N <= 20

Analysis:
Firstly, we can get several inferences from the problem:

  1. If a tree is a full binary tree, then the amount of all its nodes must be odd because every node(except the root node) can be made a pair with another son node of its parent node( 2 ∗ p a i r N u m b e r + 1 2 * pairNumber + 1 2pairNumber+1).
  2. If a tree is a full binary tree, then its left subtree and right subtree(if exists) are also full binary trees, and the amount of nodes in each subtree is also odd.

Secondly, we use FBT(N) to denote a full binary tree with N nodes.
Then its left subtree and right subtree can be denoted as FBT(i) and FBT(N-1-i) respectively where i is an odd.
We can use a recursion to get a list of root nodes of FBT(i) and a list of root nodes of FBT(N-1-i) . Then do the combination of items in two lists to create a list of root nodes of FBT(N).


Code:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<TreeNode> allPossibleFBT(int N) {
        List<TreeNode> list = new ArrayList<>();
        if(N == 1) {
            TreeNode node = new TreeNode(0);
            list.add(node);
        }else{
            for(int i = 1; i <= N-2; i+=2) {
            	// a list of root nodes of left subtree 
                List<TreeNode> leftFBT = allPossibleFBT(i);
                // a list of root nodes of right subtree 
                List<TreeNode> rightFBT = allPossibleFBT(N-1-i);
                // do the combination
                for(TreeNode l: leftFBT) {
                    for(TreeNode r: rightFBT) {
                        TreeNode root = new TreeNode(0);
                        root.left = l;
                        root.right = r;
                        list.add(root);
                    }
                }
            }
        }
        return list;
    }
}

Tweak:
In the above solution, we may repeatedly calculate some results. For example, N = 7 is given, if the left subtree has 1 node and the right subtree has 5 nodes, we will calculate FBT(1) and FBT(5). However, with the progress of a loop, if the left subtree has 5 nodes and the right tree has 1 node we will repeatedly calculate FBT(5) and FBT(1). So we add a memory search strategy to our solution which uses a hash map to store the calculated results.

Code:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    Map<Integer, List<TreeNode>> memo = new HashMap<>(); // memory
        
    public List<TreeNode> allPossibleFBT(int N) {
        if(!memo.containsKey(N)) { // memory search
            List<TreeNode> FBT = new ArrayList<>();
            if(N == 1) {
                TreeNode node = new TreeNode(0);
                FBT.add(node);
            }else{
                for(int i = 1; i <= N-2; i+=2) {
                	// a list of root nodes of left subtree 
                    List<TreeNode> leftFBT = allPossibleFBT(i);
                    // a list of root nodes of right subtree 
                    List<TreeNode> rightFBT = allPossibleFBT(N-1-i);
                    // do the combination
                    for(TreeNode l: leftFBT) {
                        for(TreeNode r: rightFBT ) {
                            TreeNode root = new TreeNode(0);
                            root.left = l;
                            root.right = r;
                            FBT.add(root);
                        }
                    }
                   
                }
            }
            memo.put(N, FBT); // add the calculated result to the memory
            return FBT;
        }else{
            return memo.get(N);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值