分治题目:所有可能的真二叉树

题目

标题和出处

标题:所有可能的真二叉树

出处:894. 所有可能的真二叉树

难度

5 级

题目描述

要求

给定一个整数 n \texttt{n} n,返回所有含 n \texttt{n} n 个结点的真二叉树的列表。答案中每个树的每个结点值都必须是 0 \texttt{0} 0

答案的每个元素都是一个真二叉树的根结点。可以按任意顺序返回答案。

真二叉树是一类二叉树,树中每个结点恰好有 0 \texttt{0} 0 2 \texttt{2} 2 个子结点。

示例

示例 1:

示例 1

输入: n   =   7 \texttt{n = 7} n = 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]] \texttt{[[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]]} [[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]]

示例 2:

输入: n   =   3 \texttt{n = 3} n = 3
输出: [[0,0,0]] \texttt{[[0,0,0]]} [[0,0,0]]

数据范围

  • 1 ≤ n ≤ 20 \texttt{1} \le \texttt{n} \le \texttt{20} 1n20

解法

思路和算法

根据真二叉树的定义,真二叉树中的每个结点的子结点数是 0 0 0 2 2 2。真二叉树中的结点数是奇数,可以使用数学归纳法证明。

  1. 当二叉树中只有一个结点时,唯一的结点是根结点,没有子结点,因此是真二叉树,此时真二叉树中的结点数是奇数。

  2. 当真二叉树中有 m m m 个结点时,将其中一个叶结点增加两个子结点之后仍为真二叉树,新的真二叉树中有 m + 2 m + 2 m+2 个结点,当 m m m 是奇数时, m + 2 m + 2 m+2 也是奇数。

由于真二叉树中的结点数一定是奇数,因此当 n n n 是偶数时不存在真二叉树,返回空列表。

n n n 是奇数时, n n n 个结点的真二叉树满足左子树和右子树的结点数都是奇数且左子树和右子树的结点数之和是 n − 1 n - 1 n1,分别构造根结点的左子树和右子树,即可得到 n n n 个结点的真二叉树。这是一个递归分治的过程。

分治的终止条件是 n n n 是偶数和 n = 1 n = 1 n=1,当 n n n 是偶数时不存在真二叉树,当 n = 1 n = 1 n=1 时只有一个结点的二叉树是真二叉树。当 n > 1 n > 1 n>1 n n n 是奇数时,遍历左子树和右子树的结点数,然后递归地构造左子树和右子树。

确定左子树和右子树的结点数之后,用 leftSubtrees \textit{leftSubtrees} leftSubtrees rightSubtrees \textit{rightSubtrees} rightSubtrees 分别表示符合要求的左子树列表和右子树列表,对于任意 leftSubtree ∈ leftSubtrees \textit{leftSubtree} \in \textit{leftSubtrees} leftSubtreeleftSubtrees rightSubtree ∈ rightSubtrees \textit{rightSubtree} \in \textit{rightSubtrees} rightSubtreerightSubtrees,将 leftSubtree \textit{leftSubtree} leftSubtree rightSubtree \textit{rightSubtree} rightSubtree 分别作为根结点的左子树和右子树,即可得到一个真二叉树。

代码

class Solution {
    public List<TreeNode> allPossibleFBT(int n) {
        List<TreeNode> fullBinaryTrees = new ArrayList<TreeNode>();
        if (n % 2 == 0) {
            return fullBinaryTrees;
        }
        if (n == 1) {
            fullBinaryTrees.add(new TreeNode(0));
            return fullBinaryTrees;
        }
        for (int left = 1, right = n - 2; left < n; left++, right--) {
            List<TreeNode> leftSubtrees = allPossibleFBT(left);
            List<TreeNode> rightSubtrees = allPossibleFBT(right);
            for (TreeNode leftSubtree : leftSubtrees) {
                for (TreeNode rightSubtree : rightSubtrees) {
                    TreeNode root = new TreeNode(0, leftSubtree, rightSubtree);
                    fullBinaryTrees.add(root);
                }
            }
        }
        return fullBinaryTrees;
    }
}

复杂度分析

  • 时间复杂度: O ( 2 n n ) O(\dfrac{2^n}{\sqrt{n}}) O(n 2n),其中 n n n 是真二叉树的结点数。只有当 n n n 是奇数时才存在真二叉树,记 n = 2 k + 1 n = 2k + 1 n=2k+1,由 n n n 个结点组成的真二叉树的数量是第 k k k 个卡特兰数 C ( 2 k , k ) k + 1 \dfrac{C(2k, k)}{k + 1} k+1C(2k,k),其渐进上界为 O ( 4 k k k ) = O ( 2 n n n ) O(\dfrac{4^k}{k \sqrt{k}}) = O(\dfrac{2^n}{n \sqrt{n}}) O(kk 4k)=O(nn 2n),对于每个真二叉树需要 O ( n ) O(n) O(n) 的时间生成和添加到答案中,因此时间复杂度是 O ( 2 n n ) O(\dfrac{2^n}{\sqrt{n}}) O(n 2n)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是真二叉树的结点数。递归调用栈需要 O ( n ) O(n) O(n) 的空间。注意返回值不计入空间复杂度。

后记

此处提供的解法为分治。由于同一个结点值范围的子树可能被多次计算,因此可以使用记忆化。这道题中的结点数不超过 20 20 20,因此使用记忆化并不能显著提升性能。

读者可以自行尝试使用记忆化的实现。

内容概要:本文系统研究了在有限控制集约束下,三相并网逆变器中电流与功率双模态模型预测控制(MPC)的等效机理及其性能边界。通过构建精确的预测模型,设计合理的代价函数,并结合Simulink仿真与Matlab代码实现,深入分析了电流预测控制与功率预测控制两种策略在动态响应速度、稳态精度、谐波抑制能力和抗扰性等方面的差异与内在联系。研究揭示了在特定系统参数和运行条件下,两种控制模式之间的等效转化机制,并界定了各自的适用范围与性能极限。同时,探讨了多模态控制的切换逻辑、实时性优化及预测模型不确定性对控制性能的影响,旨在提升逆变器在复杂电网环境下的综合控制品质与鲁棒性。; 适合人群:具备电力电子、自动控制或新能源并网等相关专业背景,熟悉Matlab/Simulink仿真环境,从事研究生及以上层次科研或从事高端电力电子装备研发的工程技术人员。; 使用场景及目标:①深入理解模型预测控制在并网逆变器中的具体实现方法与理论基础;②掌握电流与功率双模态MPC控制器的设计、仿真建模与性能对比评估流程;③为高动态、高精度并网控制系统的方案选型、参数优化与工程化应用提供坚实的理论依据和技术参考。; 阅读建议:建议结合所提供的Simulink仿真模型与Matlab源代码进行同步实验验证,重点关注预测模型的建立过程、控制律的数学推导以及不同工况下的仿真结果对比分析,宜配合现代控制理论、电力电子变换技术及并网标准等相关资料进行系统性学习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值