leetcode 894. 所有可能的满二叉树

满二叉树,用递归的方法做,
首先它不是奇数,直接返回错误。
返回所有满二叉树
输出是从左到右,从上到下来输出的

首先,你需要用一个满二叉树来做吗?但是这样的确挺简单的。。。并且由于输出特殊,你没有什么办法求得一个比较好的结构,但是用二叉树和递归的方法做,首先,每一层都要么添加两个子节点,要么不添加,等到差不多到头后,就进行输出,因此,如果能够定位的话,就不用二叉树也没关系。。。

也就是说,它可以对null节点也可以进行设置,但设置为1就能记录了。

因为最终结果是一个完全二叉树的形式,因此,
0 1 2 3 4 5 6 7
返回形式是,如果有节点,就返回节点,不返回双层null,不返回最下面一层下面的null,看来还是树比较好做。

N是有1~20的限制,开来并不是很难做

现在的一个问题是,如何从右往左进行输出呢?用队列的方法,首先设置一个队列,然后把头节点放入,接下来进行循环了

头节点出,进入两个子节点,如果节点值为1,就不再进行压入了

真自闭,大概选用了一个最复杂的方法。。。

看看题解上的,
class Solution {
// 定义了一个哈希表,作为最后结果
    Map<Integer, List<TreeNode>> memo = new HashMap();
// 主函数
    public List<TreeNode> allPossibleFBT(int N) {
        if (!memo.containsKey(N)) { // 如果没有包含最后一个键
            List<TreeNode> ans = new LinkedList(); // 新建一个结果
            if (N == 1) { // N=1的时候特别处理
                ans.add(new TreeNode(0));
            }
else if (N % 2 == 1) { // 如果是个奇数
                for (int x = 0; x < N; ++x) { // 从0开始
                    int y = N - 1 - x; // 然后设置y
                    for (TreeNode left: allPossibleFBT(x)) // 对于左边的,还是一个递归。。
                    // 是下一层的循环
                        for (TreeNode right: allPossibleFBT(y)) { // 对于右边的
                            TreeNode bns = new TreeNode(0); // 新建一个节点
                            bns.left = left; // 添加个什么鬼
                            bns.right = right;
                            ans.add(bns); // 然后就能添加进去的,单纯结果
                        }
                }
            }
            memo.put(N, ans);//然后,所有。。。不知道啥意思,但就大概这意思
//有一个问题就是,它并没有层序输出啊??但它用了三层循环
        }

        return memo.get(N);
    }
}

每个满二叉树 TT 含有 3 个或更多结点,在其根结点处有 2 个子结点。这些子结点 left 和 right 本身就是满二叉树。

因此,对于 N \geq 3N≥3,我们可以设定如下的递归策略:\text{FBT}(N) =FBT(N)= [对于所有的 xx,所有的树的左子结点来自 \text{FBT}(x)FBT(x) 而右子结点来自 \text{FBT}(N-1-x)FBT(N−1−x)]。

此外,通过简单的计数参数,没有满二叉树具有正偶数个结点。

最后,我们应该缓存函数 \text{FBT}FBT 之前的结果,这样我们就不必在递归中重新计算它们。

等等,它返回的是个二叉树唉。。。也并没有说,是按照层序的,首先,这个函数是返回一个二叉树的列表,各种各样的列表,两层嵌套循环得到的就是m*n性质的列表,列表里都是头指针。。。苍天,原来这样。。。真是自闭,看错题了

















 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值