news 2026/8/19 16:28:16

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
分治题目:所有可能的真二叉树

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析
  • 后记

题目

标题和出处

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

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

难度

5 级

题目描述

要求

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

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

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

示例

示例 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 002 22。真二叉树中的结点数是奇数,可以使用数学归纳法证明。

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

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

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

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

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

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

代码

classSolution{publicList<TreeNode>allPossibleFBT(intn){List<TreeNode>fullBinaryTrees=newArrayList<TreeNode>();if(n%2==0){returnfullBinaryTrees;}if(n==1){fullBinaryTrees.add(newTreeNode(0));returnfullBinaryTrees;}for(intleft=1,right=n-2;left<n;left++,right--){List<TreeNode>leftSubtrees=allPossibleFBT(left);List<TreeNode>rightSubtrees=allPossibleFBT(right);for(TreeNodeleftSubtree:leftSubtrees){for(TreeNoderightSubtree:rightSubtrees){TreeNoderoot=newTreeNode(0,leftSubtree,rightSubtree);fullBinaryTrees.add(root);}}}returnfullBinaryTrees;}}

复杂度分析

  • 时间复杂度:O ( 2 n n ) O(\dfrac{2^n}{\sqrt{n}})O(n2n),其中n nn是真二叉树的结点数。只有当n nn是奇数时才存在真二叉树,记n = 2 k + 1 n = 2k + 1n=2k+1,由n nn个结点组成的真二叉树的数量是第k kk个卡特兰数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(kk4k)=O(nn2n),对于每个真二叉树需要O ( n ) O(n)O(n)的时间生成和添加到答案中,因此时间复杂度是O ( 2 n n ) O(\dfrac{2^n}{\sqrt{n}})O(n2n)

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

后记

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/19 16:25:27

极简产品升级前的核对清单

极简产品升级前的核对清单 早上 9 点刚推完版本更新&#xff0c;客服渠道就被打爆了。旧版本 APP 的用户打开软件直接白屏&#xff0c;终端日志里铺天盖地全是 TypeError: Cannot read properties of undefined (reading v2_profile)。 系统升级时&#xff0c;删除旧字段可能破…

作者头像 李华
网站建设 2026/8/19 16:23:37

SAP-QM QS27 替换主检验特性

问题&#xff1a;需要更新主检验特性&#xff0c;由于主检验特性需要修改范围&#xff0c;但是已经分配给检验计划里面了。 我在系统里面新建了一个主检验特性&#xff0c;准备替换掉原来的主检验特性&#xff0c;然后发现不管怎么操作&#xff0c;就是无法替换掉&#xff0c;而…

作者头像 李华
网站建设 2026/8/19 16:22:51

【专题05】Kubernetes面试题(50题)

核心概念&#xff08;15题&#xff09; 1、K8s架构和组件 Kubernetes (通常简称为 K8s) 是一个开源的容器编排引擎&#xff0c;用于自动化部署、扩展和管理容器化应用程序。 K8s 采用 主从架构 (Master-Worker Architecture)&#xff0c;整个集群主要由两部分组成&#xff1a; …

作者头像 李华
网站建设 2026/8/19 16:18:24

ATtiny10驱动OLED:1KB闪存下的嵌入式图形显示极限实践

1. 项目概述&#xff1a;当最小MCU遇见OLED 在嵌入式开发的世界里&#xff0c;我们常常追求“小而美”的极致。你是否想过&#xff0c;用一颗仅有6个引脚、1KB闪存、32字节RAM的ATtiny10微控制器&#xff0c;去驱动一块128x64分辨率的OLED显示屏&#xff1f;这听起来像是一场“…

作者头像 李华
网站建设 2026/8/19 16:15:57

SimpylFold 使用技巧:10 个必学的 Vim 代码折叠命令

SimpylFold 使用技巧&#xff1a;10 个必学的 Vim 代码折叠命令 【免费下载链接】SimpylFold No-BS Python code folding for Vim 项目地址: https://gitcode.com/gh_mirrors/si/SimpylFold SimpylFold 是一款专为 Python 打造的 Vim 代码折叠插件&#xff0c;它只智能折…

作者头像 李华
网站建设 2026/8/19 16:15:52

RT-Thread启动流程全解析:从硬件上电到多任务调度

1. 从按下电源到第一个线程&#xff1a;RT-Thread的启动全景 很多嵌入式开发者对RT-Thread的认知&#xff0c;可能始于 rt_thread_create 和 rt_thread_startup &#xff0c;但一个线程真正跑起来之前&#xff0c;系统已经默默做了大量工作。今天&#xff0c;我们就从最底层…

作者头像 李华