分治dp,LeetCode 894. 所有可能的真二叉树

news2024/11/28 0:30:59

目录

一、题目

1、题目描述

2、接口描述

​cpp

python3

3、原题链接

二、解题报告

1、思路分析

F1 回溯

F2 动态规划

2、复杂度

3、代码详解

​分治

cpp

python3

dp

cpp

python3


一、题目

1、题目描述

给你一个整数 n ,请你找出所有可能含 n 个节点的 真二叉树 ,并以列表形式返回。答案中每棵树的每个节点都必须符合 Node.val == 0 。

答案的每个元素都是一棵真二叉树的根节点。你可以按 任意顺序 返回最终的真二叉树列表

真二叉树 是一类二叉树,树中每个节点恰好有 0 或 2 个子节点。

2、接口描述

​cpp
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<TreeNode*> allPossibleFBT(int n) {

    }
};
python3
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def allPossibleFBT(self, n: int) -> List[Optional[TreeNode]]:

3、原题链接

894. 所有可能的真二叉树


二、解题报告

1、思路分析

F1 回溯

首先对于偶数个节点的情况直接返回空即可

然后分析,对于n(n为奇数)个节点的二叉树,根节点占一个节点,那么其左右节点的情况为

<1, n - 2>, <3, n - 4>……

所以我们发现构造n个节点的真二叉树可以分治为构造两个子真二叉树的问题

所以我们枚举左右儿子的节点数目进行分治构造即可

F2 动态规划

我们可以换种思路,自底向上分析

对于n个节点的真二叉树可以分为根节点加上两个子真二叉树

同样的,我们也可以由两个子真二叉树构造出一棵真二叉树

我们设f[k](k >= 1)为n = 2 * k - 1个节点的真二叉树的所有可能序列

那么f[i] = node(f[k], f[i - k]),这个递推还是比较简单的

相较于分治的做法,时间复杂度并未降低,但是省去了递归开销 

由于数据量只到20,因此我们可以预处理出f[1]~f[10]

2、复杂度

分治:时间复杂度:O(\frac{4_{}^{n}}{n_{}^{3/2}}) 空间复杂度:O(\frac{4_{}^{n}}{n_{}^{3/2}})

dp:预处理时间复杂度O(\frac{4_{}^{N}}{N_{}^{3/2}})预处理空间复杂度:O(\frac{4_{}^{N}}{N_{}^{3/2}}),N = 11

查询的时间复杂度和空间复杂度都是O(1)

3、代码详解

​分治
cpp
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<TreeNode*> allPossibleFBT(int n) {
        vector<TreeNode*> ret;
        if(n % 2 == 0) return ret;
        if(n == 1) return {new TreeNode(0)};
        for(int i = 1; i < n; i += 2){
            vector<TreeNode*> leftnodes(allPossibleFBT(i)), rightnodes(allPossibleFBT(n - i - 1));
            for(TreeNode* x : leftnodes)
                for(TreeNode* y : rightnodes)
                    ret.emplace_back(new TreeNode(0, x, y));
        }
        return ret;
    }
};
python3
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def allPossibleFBT(self, n: int) -> List[Optional[TreeNode]]:
        if n % 2 == 0:
            return []
        if n == 1:
            return [TreeNode()]
        ret = []
        for i in range(1, n, 2):
            leftnodes, rightnodes = self.allPossibleFBT(i), self.allPossibleFBT(n - i - 1)
            ret.extend([TreeNode(0, x, y) for x in leftnodes for y in rightnodes])
        return ret

python也可以记忆化搜索,得到和dp相媲美的效率

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    @cache
    def allPossibleFBT(self, n: int) -> List[Optional[TreeNode]]:
        if n % 2 == 0:
            return []
        if n == 1:
            return [TreeNode()]
        ret = []
        for i in range(1, n, 2):
            leftnodes, rightnodes = self.allPossibleFBT(i), self.allPossibleFBT(n - i - 1)
            ret.extend([TreeNode(0, x, y) for x in leftnodes for y in rightnodes])
        return ret

dp
cpp
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
vector<TreeNode*> f[11];
bool init = []{
    f[1] = { new TreeNode() };
    for(int i = 2; i < 11; i++)
        for(int j = 1; j < i; j++)
            for(TreeNode* x : f[j])
                for(TreeNode* y : f[i - j])
                    f[i].emplace_back(new TreeNode(0, x, y));
    return false;
}();
class Solution {
public:
    vector<TreeNode*> allPossibleFBT(int n) {
        return f[n & 1 ? (n + 1) / 2 : 0];
    }
};
python3
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
f = [[] for _ in range(11)]
f[1] = [TreeNode()]
for i in range(2, 11):
    f[i] = [TreeNode(0, x, y) 
            for j in range(1, i)
                for x in f[j]
                    for y in f[i - j]]
class Solution:
    def allPossibleFBT(self, n: int) -> List[Optional[TreeNode]]:
        return f[(n + 1) // 2] if n & 1 else []

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1562718.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数学矩阵(详解)

矩阵乘法 知阵乘法是《线性代数》中的基础内容&#xff0c;但在考察数学的算法题中也会出现。 本节我们学习基础的矩阵乘法规则。 每个矩阵会有一个行数和一个列数&#xff0c;只有当相乘的两个矩阵的左矩阵的列数等于右矩阵的行数 时&#xff0c;才能相乘&#xff0c;否则不允…

蓝桥杯单片机速成2-动态数码管数码管显示

一、原理图 段选给1是选中 &#xff0c;该数码管是共阳极的数码管&#xff0c;位选输入0才会电亮一位 二、代码分析 /************* 本地常量声明 **************/ u8 code t_display[]{ //标准字库 // 0 1 2 3 4 5 6 7 8…

Java复习第十五天学习笔记(JS),附有道云笔记链接

一、JS简介 JS&#xff1a; 1、直接嵌入HTML页面。 2、由浏览器解释执行代码&#xff0c;不进行预编译。 解释型语言和编译型语言 JS&#xff1a;解释型语言、弱类型语言 Java:编译型语言、强类型语言 变量: var num 100; variable 用var来定义一个变量。 int num 1…

kubernetes(K8S)学习(九):K8S之日志监控

K8S之日志监控 一、Log and Monitor1.1 Log1.1.1 容器级别1.1.2 Pod级别1.1.3 组件服务级别1.1.4 LogPilot ES Kibana 1.2 Monitor1.2.1 Prometheus简介1.2.2 Prometheus架构1.2.3 Prometheus知识普及1.2.4 数据采集1.2.5 Prometheus Grafana 二、Trouble Shooting&#xff…

ARM64架构栈帧以及帧指针FP

文章目录 前言一、arm64架构寄存器简介1.1 异常等级1.2 通用寄存器1.3 ARM64架构ABI 二、ARM64架构函数调用标准2.1 AArch64过程调用标准简介2.2 通用寄存器中的参数 三、demo分析3.1 main函数3.2 funb3.3 funa 四、栈帧总结五、demo演示参考资料 前言 这篇文章描述了 x86_64架…

原生小程序开发性能优化指南

性能优化指南 1.骨架屏 业务可以在数据加载完成之前用骨架屏幕来占位&#xff0c;提升体验。 2.包大小优化 减小包中静态资源&#xff0c;例如图片文件&#xff0c;可将图片进行压缩降低文件体积。无用文件、函数、样式剔除。除了部分用于容错的图片必须放在代码包&#xf…

3.docker容器相关命令

docker容器相关命令 容器是根据镜像创建的 docker images 1.查看容器 docker ps docker ps -a #查看所有容器 2.创建容器 docker run -itd --name XXX nginx /bin/bash docker run -it -name xxxxx centos:7 参数&#xff1a;-i :一直运行着 -t : 给容器分配一个终端…

CentOS7安装DockerCompose

1.CentOS7安装DockerCompose 1.1.下载 Linux下需要通过命令下载&#xff1a; # 安装 curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-uname -s-uname -m > /usr/local/bin/docker-compose1.2.修改文件权限 修改文件权限&#xff1a…

汽车电子行业知识:什么是数字钥匙?

文章目录 1. 什么是数字钥匙&#xff1f;2. 数字钥匙有哪些类型&#xff1f;3. 汽车数字钥匙4. 数字钥匙包含哪些技术5. 汽车数字钥匙的发展趋势 1. 什么是数字钥匙&#xff1f; 数字钥匙通常指的是一种安全工具&#xff0c;它使用数字代码或密码来授权对特定系统或服务的访问。…

练习 13 Web [极客大挑战 2019]Secret File

php伪协议请求&#xff0c;php代码审计 参考&#xff1a;BUUCTF__[极客大挑战 2019]Secret File_题解 没有任何上传和登录页面 查看前端源码 发现 <a id"master" href"./Archive_room.php" style"background-color:#000000;height:70px;width:20…

Linux中间件(nginx搭建、LNMP服务搭建)

目录 一、安装nginx 第一步、下载nginx的压缩包到Linux中 ​第二步、安装依赖 第三步&#xff1a;安装 nginx 第四步&#xff1a;启动nginx 第五步&#xff1a;测试nginx 二、 nginx的配置文件 nginx.conf文件内容解读 案例&#xff1a;发布多个网站 二、lamp/lnmp …

springcloud基本使用二(远程调用)

创建两个springboot maven子项目 子项目名称分别为order-server和user-server 配置user-server子项目: 所需依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependenc…

如何用Git在终端以可视化的方式查看提交情况

2024年4月2日&#xff0c;周二上午 要使用 Git 查看树状提交情况&#xff0c;可以使用 git log 命令的 --graph 选项。这个选项会以树状图的形式显示提交历史&#xff0c;清晰地展示每个提交的分支合并情况和分支间的关系。 git log --graph 除了 --graph 选项外&#xff0c;还…

算法学习——LeetCode力扣动态规划篇1(509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯、62. 不同路径、63. 不同路径 II)

算法学习——LeetCode力扣动态规划篇1 509. 斐波那契数 509. 斐波那契数 - 力扣&#xff08;LeetCode&#xff09; 描述 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项…

Mac - Keychron K3 Pro 功能键改键 -via 改键配置 For Mac

前言 Keychron K3 Pro键盘连接Mac使用&#xff0c;顶部一排功能键&#xff0c;默认是Mac的多媒体功能键。F1&#xff5e;F12功能键&#xff0c;需要按&#xff1a;Fn F1&#xff5e;F12。 而在我的日常工作中&#xff0c;常用的是F1&#xff5e;F12&#xff0c;期望F1~F12功…

SwiftUI Swift 显示隐藏系统顶部状态栏

Show me the code // // TestHideSystemTopBar.swift // pandabill // // Created by 朱洪苇 on 2024/4/1. //import SwiftUIstruct TestHideSystemTopBar: View {State private var isStatusBarHidden falsevar body: some View {Button {withAnimation {self.isStatusBa…

一文入门Ubuntu22

目录 1.安装Ubuntu22 2.常用目录 3.常用指令 1.sudo 超级用户权限运行命令 2.ls 罗列当前文件信息 3.文件目录相关&#xff1a; 1.cd改变工作路径&#xff1a; 2.pwd 3.创建目录和文件&#xff1a; 4.which 5.ps 6.kill 7.ping 4.用户相关 5.ssh与scp 6.服务相关…

宝塔面板 -- 打包前端项目并部署提升访问速度

文章目录 前言一、打包前端项目二、添加PHP项目三、部署打包文件四、开通防火墙五、运行网站总结 前言 在前面写到的文章使用宝塔面板部署前端项目中&#xff0c;并没有将前端项目打包而是直接部署&#xff0c;导致网站访问速度非常慢&#xff0c;加载甚至要十几秒。因此&…

HarmonyOS 应用开发之featureAbility接口切换particleAbility接口切换

featureAbility接口切换 FA模型接口Stage模型接口对应d.ts文件Stage模型对应接口getWant(callback: AsyncCallback<Want>): void; getWant(): Promise<Want>;ohos.app.ability.UIAbility.d.tslaunchWant: Want;startAbility(parameter: StartAbilityParameter, c…

照片变漫画怎么制作?3种方法教会你

照片变漫画怎么制作&#xff1f;在数字化时代&#xff0c;图片处理技术日新月异&#xff0c;将照片转化为漫画风格已成为一种流行的创意表达方式。这种转变不仅能让普通照片焕发新生&#xff0c;还能为我们的社交媒体和创作平台增添一抹独特的色彩。无论是为了记录生活点滴&…