秋招算法备战第41天 | 343. 整数拆分、96.不同的二叉搜索树

343. 整数拆分 - 力扣(LeetCode)

数学方法

观察数字拆分的模式,我们可以发现以下事实:

  1. 将数字拆分为尽可能多的3会使乘积最大化。这是因为当 n > 4 时,3(n-3) > n,所以我们总是更喜欢3的拆分,而不是保持n。
  2. 当剩下的数字为4时,拆分为2 * 2是更好的选择。

根据上面的事实,我们可以写出以下算法:

  1. 如果 n == 2,返回1(因为2只能拆分为1 + 1)。
  2. 如果 n == 3,返回2(因为3只能拆分为2 + 1)。
  3. 如果 n == 4,返回4(因为4可以拆分为2 + 2)。
  4. 对于所有其他的 n,我们可以采用如下方式计算结果:
    • 用 n 除以3,得到商 a 和余数 b。
    • 如果 b == 0,则结果为 3^a。
    • 如果 b == 1,则结果为 3^(a-1) * 4(我们从三的倍数中拿出一个3与余数1组成4)。
    • 如果 b == 2,则结果为 3^a * 2。

以下是基于上述方法的Python实现:

def integerBreak(n: int) -> int:if n == 2:return 1if n == 3:return 2if n == 4:return 4# n > 4a, b = divmod(n, 3)if b == 0:return 3**aelif b == 1:return 3**(a-1) * 4else:  # b == 2return 3**a * 2# 测试
print(integerBreak(2))  # 输出:1
print(integerBreak(10)) # 输出:36

这种方法的时间复杂度是 O(1),因为我们只是做了一些数学计算。

动态规划

对于整数拆分问题,动态规划的一个直观思路是使用一个数组 dp,其中 dp[i] 表示数字 i 拆分后的最大乘积。

我们的目标是填充这个数组,以便 dp[n] 给出答案。

递推关系的建立需要考虑如何拆分整数 i。对于任何小于 i 的正整数 j,我们可以将 i 拆分为 j 和 i-j。这两个数字可以进一步拆分或保持原样。因此,乘积的最大值是 max(j, dp[j]) * max(i-j, dp[i-j])。

要计算 dp[i],我们考虑所有可能的 j(从1到i/2),并采取上述乘积的最大值。

基于上述逻辑,我们可以为问题建立动态规划解决方案。

def integerBreak(n: int) -> int:# dp[i] 表示数字 i 拆分后的最大乘积dp = [0] * (n+1)dp[1] = 1for i in range(2, n+1):for j in range(1, i//2 + 1):dp[i] = max(dp[i], max(j, dp[j]) * max(i-j, dp[i-j]))return dp[n]# 测试
print(integerBreak(2))  # 输出:1
print(integerBreak(10)) # 输出:36

这种动态规划方法的时间复杂度是 O(n^2),因为我们使用了两层循环来填充 dp 数组。

动态规划优化

优化动态规划的方法涉及减少不必要的计算。对于整数拆分问题,我们注意到当我们选择拆分整数 iji-j 时,由于问题是对称的,我们实际上只需要考虑从 1i//2 的整数 j。因此,我们可以减少一半的计算。

考虑到这一点,我们仍然需要确定如何拆分整数以获得最大的乘积。动态规划的核心仍然是使用 dp 数组,其中 dp[i] 表示整数 i 被拆分后的最大乘积。

考虑到我们的数学方法,整数3和2是最关键的因素。我们可以进一步优化我们的动态规划解决方案,使其更接近数学解决方案,但仍然使用动态规划的框架。

这是优化后的解决方案:

def integerBreak(n: int) -> int:if n == 2: return 1if n == 3:return 2# dp[i] 表示数字 i 拆分后的最大乘积dp = [0] * (n+1)# 基本情况dp[1], dp[2], dp[3] = 1, 2, 3for i in range(4, n+1):# 因为问题对称,我们只考虑从1到i//2的整数jfor j in range(1, i//2 + 1):dp[i] = max(dp[i], dp[j] * dp[i-j])return dp[n]# 测试
print(integerBreak(2))  # 输出:1
print(integerBreak(10)) # 输出:36

尽管外观上与先前的动态规划解决方案相似,但这个解决方案的性能更好,因为它减少了不必要的计算,并且更加接近数学解决方案的思路。

96. 不同的二叉搜索树 - 力扣(LeetCode)

这个问题可以使用动态规划来解决,基于以下观察:

当我们尝试构建一个二叉搜索树时,我们可以选择一个数字作为根。如果我们选择数字 i 作为根,那么所有小于 i 的数字必须位于它的左子树中,而所有大于 i 的数字则必须位于它的右子树中。

因此,对于一个给定的根 i,数量是:左子树的数量乘以右子树的数量。

我们可以使用动态规划来计算所有可能数量的总和。定义数组 G,其中 G[n] 表示长度为 n 的序列的不同二叉搜索树的数量。

给定序列 1 … n,我们从序列中选择一个数字 i,将该数作为根,将 1 … (i-1) 序列作为左子树,将 (i+1) … n 序列作为右子树。因此,我们可以得出以下公式:

[ G(n) = G(0) \times G(n-1) + G(1) \times G(n-2) + … + G(n-1) \times G(0) ]

具体解决方案如下:

def numTrees(n: int) -> int:G = [0] * (n + 1)G[0], G[1] = 1, 1for i in range(2, n + 1):for j in range(1, i + 1):G[i] += G[j - 1] * G[i - j]return G[n]# 测试
print(numTrees(3))  # 输出:5
print(numTrees(1))  # 输出:1

这个方法的时间复杂度是 ( O(n^2) )。

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

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

相关文章

【Spring专题】Spring底层核心原理解析

目录 前言阅读导航前置知识Q1:你能描述一下JVM对象创建过程吗?Q2:Spring的特性是什么?前置知识总结 课程内容一、Spring容器的启动二、一般流程推测2.1 扫描2.2 IOC2.3 AOP 2.4 小结三、【扫描】过程简单推测四、【IOC】过程简单推…

laravel\lumen rabbitmq

1、安装扩展 composer require bschmitt/laravel-amqp 2、config文件下增加amqp.php配置文件 <?phpreturn [/*|--------------------------------------------------------------------------| Define which configuration should be used|----------------------------…

c++ STL--容器 (第二部分)

c STL–容器 &#xff08;第二部分&#xff09; 1.vector向量&#xff08;序列性容器&#xff09; 1.特点&#xff1a; ​ 数据的存储访问比较方便&#xff0c;可以像数组一阿姨那个使用[index]访问或修改值&#xff0c;适用于对元素修改和查看比较多的情况&#xff0c;对于…

数据库--MySQL

一、什么是范式&#xff1f; 范式是数据库设计时遵循的一种规范&#xff0c;不同的规范要求遵循不同的范式。 最常用的三大范式 第一范式(1NF)&#xff1a;属性不可分割&#xff0c;即每个属性都是不可分割的原子项。(实体的属性即表中的列) 第二范式(2NF)&#xff1a;满足…

代码随想录day03

链表理论基础 ● 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点有两个部分&#xff0c;数据域和指针域&#xff0c;最后一个节点指针域指向null 链表类型 ● 单链表 ● 双链表 ○ 每个节点有两个指针域&#xff0c;一个指向下一个节点&#xff0c;一个是上…

企业级帮助中心编写方案怎么写?

在现代商业环境中&#xff0c;为客户提供高效的支持和解决方案至关重要。企业级帮助中心是一个集中管理和呈现常见问题和解答的平台&#xff0c;可以为客户提供快速、便捷的自助帮助。本文将提供一个企业级帮助中心编写方案&#xff0c;旨在帮助企业提供优质的客户支持&#xf…

【ARM 嵌入式 编译系列 3.1 -- GCC __attribute__((used)) 使用】

文章目录 __attribute__((used)) 属性介绍代码演示编译与输出GCC 编译选项 上篇文章&#xff1a;ARM 嵌入式 编译系列 3 – GCC attribute((weak)) 弱符号使用 下篇文章&#xff1a;ARM 嵌入式 编译系列 3.2 – glibc 学习 __attribute__((used)) 属性介绍 在普通的 C/C 程序中…

20.4 HTML 表单

1. form表单 <form>标签: 用于创建一个表单, 通过表单, 用户可以向网站提交数据. 表单可以包含文本输入字段, 复选框, 单选按钮, 下拉列表, 提交按钮等等. 当用户提交表单时, 表单数据会发送到服务器进行处理.action属性: 应指向一个能够处理表单数据的服务器端脚本或UR…

在SpringBoot项目中使用线程池创建一个线程案例

目录 1. 首先,在你的Spring Boot项目的配置类中,创建一个`ThreadPoolTaskExecutor`的Bean:2. 在你的Service类中,创建一个异步方法,并使用`@Async`注解将其标记为异步方法,该方法将在线程池中执行:3. 在Controller中调用异步方法:在Spring Boot项目中使用线程池可以通过…

React入门学习笔记3

事件处理 通过onXxx属性指定事件处理函数(注意大小写) React使用的是自定义(合成)事件, 而不是使用的原生DOM事件——为了更好的兼容性 eg&#xff1a;οnclick》onClickReact中的事件是通过事件委托方式处理的(委托给组件最外层的元素)——为了更高效通过event.target得到发生…

【Express.js】软件测试

软件测试 本节介绍如何在 express.js 使用 Jest 进行单元测试 准备工作 准备一个基础的 express 项目&#xff0c;本文基于 evp-express-cli安装 Jest npm install jest --save-dev生成 Jest 配置 npx jest --init编写测试 创建测试文件&#xff0c;以 .test.js 后缀命名…

AlmaLinux 9 安装 Go 1.20

AlmaLinux 9 安装 Golang 1.20 1. 下载 go 安装包2. 安装 go3. 配置环境变量4. 确认 go 版本 1. 下载 go 安装包 访问 https://go.dev/dl/&#xff0c;下载你想安装的版本&#xff0c;比如 go1.20.7.linux-amd64.tar.gz&#xff0c; 2. 安装 go (可选)删除旧版本&#xff0c;…

CLIP论文精度

CLIP论文精度 Zero-shot CLIP多模态模型 Image Endecoder是一个图片编码器&#xff0c;既可以是ResNet,也可以是Vision Transformer. Text Encoder和Image Encoder产生的两组特征进行对比学习&#xff08;无监督训练&#xff09; 分类头&#xff1f;“分类头” 是指网络结…

matlab使用教程(13)—稀疏矩阵创建和使用

使用稀疏矩阵存储包含众多零值元素的数据&#xff0c;可以节省大量内存并加快该数据的处理速度。sparse 是一种属性&#xff0c;可以将该属性分配给由 double 或 logical 元素组成的任何二维 MATLAB 矩阵。通过 sparse 属性&#xff0c;MATLAB 可以&#xff1a; • 仅存储矩…

openGauss学习笔记-37 openGauss 高级数据管理-事务

文章目录 openGauss学习笔记-37 openGauss 高级数据管理-事务37.1 语法格式37.2 参数说明37.3 示例 openGauss学习笔记-37 openGauss 高级数据管理-事务 事务是用户定义的一个数据库操作序列&#xff0c;这些操作要么全做要么全不做&#xff0c;是一个不可分割的工作单位。ope…

SpringBoot案例-部门管理-删除

目录 查看页面原型&#xff0c;明确需求 页面原型 需求 阅读接口文档 思路分析 功能接口开发 控制层&#xff08;Controllre类&#xff09; 业务层&#xff08;Service类&#xff09; 持久层&#xff08;Mapper类&#xff09; 接口测试 前后端联调 查看页面原型&a…

全面讲解|DCMM数据管理能力成熟度及各地政策汇总

信息技术与经济社会的交汇融合引发了数据爆发式增长。数据蕴含着重要的价值&#xff0c;已成为国家基础性战略资源&#xff0c;正日益对全球生产、流通、分配、消费活动以及经济运行机制、社会生活方式和国家治理能力产生重要影响。数据价值发挥的前提是管理好数据&#xff0c;…

docker 学习笔记 (持续更新)

一些基础概念 Docker 入门教程 - 阮一峰的网络日志 什么是image文件&#xff1f; Docker 把应用程序及其依赖&#xff0c;打包在 image 文件里面。只有通过这个文件&#xff0c;才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。…

13_Ansible role、创建目录结构、Roles依赖关系;Playbook参考资料:facts、with_item、jinja模板、role角色

16.Ansible role 16.1.Ansible Roles介绍 16.2.创建目录结构 16.3.Ansible Roles依赖关系 17.其它参考资料 17.1.Playbook参考资料 17.2.Ansible facts 17.3.判断语句 when 17.4.with_items 17.5.ansible jinja模板 17.6.ansible role角色 17.7.变量其它参考文档 16.Ansible r…