894. 所有可能的真二叉树(中等)

没做出来,难受 😫
核心思想

记忆化搜索 记录n个节点时,能够形成的真二叉树。
看注释吧~
ps: 节点是复用的,也就是会有不同节点指向同一个节点。
代码

class Solution {
    // map存储 剩余n个节点时 能够形成的真二叉树 防止重复计算
    HashMap<Integer, List<TreeNode>> v;
    public List<TreeNode> allPossibleFBT(int n) {
        v = new HashMap<>();
        return allPossibleFBTHelper(n);
    }
    private List<TreeNode> allPossibleFBTHelper(int n){
        // curList 存储 以当前节点为根节点的所有真二叉树
        List<TreeNode> curList = new ArrayList<>();
        if(n == 1){
            curList.add(new TreeNode(0));
            return curList;
        }
        // 留一个给根节点 i个节点给左子树 必须是奇数才能建成真二叉树 所以i+=2
        for(int i = 1; i < n; i+=2){
            List<TreeNode> leftTree = new ArrayList<>();
            List<TreeNode> rightTree = new ArrayList<>();
            if(v.containsKey(i)){
                leftTree = v.get(i);
            }
            else{
                leftTree = allPossibleFBTHelper(i);
            }

            if(v.containsKey(n - i - 1)){
                rightTree = v.get(n - i - 1);
            }
            else{
                rightTree = allPossibleFBTHelper(n - i - 1);
            }

            // 获取所有左右子树的种类 接在当前根节点上
            for(int left = 0; left < leftTree.size(); left++){
                for(int right = 0; right < rightTree.size(); right++){
                    TreeNode root = new TreeNode(0);
                    root.left = leftTree.get(left);
                    root.right = rightTree.get(right);
                    curList.add(root);
                }
            }
        }
        v.put(n, curList);
        return curList;
    }
}
posted @ 2024-04-02 10:17  Shie1d  阅读(32)  评论(0)    收藏  举报