代码随想录算法训练营第四十一天| LeetCode343. 整数拆分、LeetCode96. 不同的二叉搜索树

news2025/1/15 12:49:21

一、LeetCode343. 整数拆分

        1:题目描述(343. 整数拆分)

        给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

        返回 你可以获得的最大乘积 。

        2:解题思路

        动态规划

        动规五部曲,分析如下:(代码随想录:整数拆分)

        1:确定dp数组(dp table)以及下标的含义

        dp[i]:分拆数字i,可以得到的最大乘积为dp[i]。

        dp[i]的定义讲贯彻整个解题过程,下面哪一步想不懂了,就想想dp[i]究竟表示的是啥!

        2:确定递推公式

        可以想 dp[i]最大乘积是怎么得到的呢?

        其实可以从1遍历j,然后有两种渠道得到dp[i].

        一个是j * (i - j) 直接相乘。

        一个是j * dp[i - j],相当于是拆分(i - j),对这个拆分不理解的话,可以回想dp数组的定义。

        j怎么就不拆分呢?

        j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。那么从1遍历j,比较(i - j) * j和dp[i - j] * j 取最大的。递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

        也可以这么理解,j * (i - j) 是单纯的把整数拆分为两个数相乘,而j * dp[i - j]是拆分成两个以及两个以上的个数相乘。

        如果定义dp[i - j] * dp[j] 也是默认将一个数强制拆成4份以及4份以上了。

        所以递推公式:dp[i] = max(dp[i],  (i - j) * j,  dp[i - j] * j);

        那么在取最大值的时候,为什么还要比较dp[i]呢?

        因为在递推公式推导的过程中,每次计算dp[i],取最大的而已。

        3:dp的初始化

        dp[0] dp[1] 就不应该初始化,也就是没有意义的数值。

        只初始化dp[2] = 1,从dp[i]的定义来说,拆分数字2,得到的最大乘积是1,这个没有任何异议!

        4:确定遍历顺序

        确定遍历顺序,先来看看递归公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

        dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]。

        枚举j的时候,是从1开始的。i是从3开始,这样dp[i - j]就是dp[2]正好可以通过我们初始化的数值求出来。

        所以遍历顺序为:从前到后

class Solution:
    def integerBreak(self, n: int) -> int:
        # 确定dp数组及其含义
        # dp[i]表示i被拆分后后,获得的最大值
        # 确定递推规则
        # 拆分为两个数:j * (i-j)
        # 拆分三个数及以上:j * dp[i-j]
        # 初始化
        # 0,1无法拆分,可以初始化为0
        # 2可以拆分为1*1,可初始化为1
        # 遍历顺序,从3开始遍历,直到遍历到n
        dp = [0] * (n+1)
        dp[2] = 1
        for i in range(3, n+1):
            for j in range(1, i):
                # 假设对正整数 i 拆分出的第一个正整数是 j(1 <= j < i),则有以下两种方案:
                # 1) 将 i 拆分成 j 和 i−j 的和,且 i−j 不再拆分成多个正整数,此时的乘积是 j * (i-j)
                # 2) 将 i 拆分成 j 和 i−j 的和,且 i−j 继续拆分成多个正整数,此时的乘积是 j * dp[i-j]
                # dp[i] = max(dp[i], max((j*(i-j)), j*dp[i-j]))
                dp[i] = max((j*(i-j)), j*dp[i-j], dp[i])
        return dp[n]

二、LeetCode96. 不同的二叉搜索树

        1:题目描述(96. 不同的二叉搜索树)

        给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

        2:解题思路

         动态规划

        动规五部曲,分析如下:(代码随想录:不同的二叉搜索数)

        1:确定dp数组(dp table)以及下标的含义

        dp[i] : 1到i为节点组成的二叉搜索树的个数为dp[i]

        也可以理解是i的不同元素节点组成的二叉搜索树的个数为dp[i] ,都是一样的。

        2:确定递推公式

        dp[i] += dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量]

        j相当于是头结点的元素,从1遍历到i为止。

        所以递推公式:dp[i] += dp[j - 1] * dp[i - j];j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量

        3:dp数组如何初始化

        初始化,只需要初始化dp[0]就可以了,推导的基础,都是dp[0]。

        从定义上来讲,空节点也是一棵二叉树,也是一棵二叉搜索树,这是可以说得通的。

        从递归公式上来讲,dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量] 中以j为头结点左子树节点数量为0,也需要dp[以j为头结点左子树节点数量] = 1, 否则乘法的结果就都变成0了。

        所以初始化dp[0] = 1

        4:确定遍历顺序

        首先一定是遍历节点数,从递归公式:dp[i] += dp[j - 1] * dp[i - j]可以看出,节点数为i的状态是依靠 i之前节点数的状态。

        那么遍历i里面每一个数作为头结点的状态,用j来遍历。

class Solution:
    def numTrees(self, n: int) -> int:
        # 1:确定dp数组及其含义
        # dp[i]表示i个节点组成的二叉搜索数有多少种
        # 2:确认递推规则
        # dp[i] += dp[j-1] * dp[i-j]  (j表示以数值j作为头节点的二叉搜索数)
        # 3:初始化
        # 只需要初始化i=0的情况,一个节点都没有,也是一种二叉搜索数
        # 4:遍历顺序
        # 从1开始遍历,到n
        dp = [0] * (n+1)
        dp[0] = 1
        for i in range(1,n+1):
            for j in range(1, i+1):
                # 对于第i个节点,需要考虑1作为根节点直到i作为根节点的情况,所以需要累加
                # 一共i个节点,对于根节点j时,左子树的节点个数为j-1,右子树的节点个数为i-j
                dp[i] += dp[j-1] * dp[i-j]
        return dp[n]

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

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

相关文章

【Linux系统】网络配置保姆级教学

目录 文章目录网络配置yum install tree 安装和tree显示Linux网络配置[原理图](https://so.csdn.net/so/search?q原理图&spm1001.2101.3001.7020)查看ip和网关ipconfig查看windows网络配置ifconfig查看Linux网络配置ping测试主机之间网络连通性Linux网络环境配置**第一种方…

在 Azure AKS 上部署 EMQX MQTT 服务器集群

云进入以「应用为中心」的云原生阶段&#xff0c;Operator 模式的出现&#xff0c;为 Kubernetes 中的自动化任务创建配置与管理提供了一套行之有效的标准规范。针对大规模分布式物联网 MQTT 消息服务器 EMQX 全生命期管理的自动化管理工具 EMQX Kubernetes Operator&#xff0…

Android最全的setContentView源码分析

前言 我们在开发过程中&#xff0c;在布局文件里添加TextView,代码运行起来就可以看到对应文字显示出来&#xff0c;那系统是如何把我们的TextView加载并显示出来的呢&#xff1f; 源码分析&#xff08;这里版本对应30&#xff09; 第一阶段 我们直接从Activity.setContent…

《第一行代码》核心知识点:Activity(活动)

Android四大组件之一&#xff1a;Activity前言二、Android四大组件之一&#xff1a;Activity(活动)2.1 活动基本介绍2.2 活动的基本用法2.2.1 如何在应用中弹出提示信息2.2.2 如何在活动中添加Menu菜单&#xff08;就一般右上角的三点&#xff09;2.2.3 如何实现活动跳转2.2.5 …

CANoe-什么是Vector Tool Platform(全网唯一讲明白的文章)

在CANoe软件:Home -> Measurement下,有一个功能项,Vector Tool Platform,是做什么用的呢? 点击后打开这个功能页面,发现界面内容不多,包含:设备选择、组件更新、系统更新、远程连接,还有一个连接状态显示 从界面功能猜测:这是一个设备管理和连接的平台。那么是什么…

购买窗帘时哪些可以不做?-江南爱窗帘十大品牌

在家居软装上&#xff0c;窗帘的选择很重要&#xff0c;因为它的存在感很强&#xff0c;占据了墙面的半壁江山。选对了&#xff0c;满心欢喜&#xff0c;选错了&#xff0c;就只能悔恨痛苦了。 1.不做拼色、花纹&#xff1a;拼色窗帘在酒店十分常见&#xff0c;但是不建议照搬回…

14 C++11线程同步之条件变量

在学习条件变量之前需要先了解下std::unique_lock;条件变量 condition_variable需要配合std::unique_lock使用&#xff1b; std::unique_lock std::unique_lock的详细细节参考此篇文章。 C11条件变量 条件变量是 C11 提供的另外一种用于等待的同步机制&#xff0c;它能阻塞…

第04章_运算符

第04章_运算符 1. 算术运算符 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xff08;/&#xff09;和取模&…

使用dbeaver连接GaussDB数据库(集中式)

服务端方式登录 默认初始用户登录方式&#xff1a; [ommgaussdb01 ~]$ gsql -d postgres -p 30100 gsql ((GaussDB Kernel V500R002C10 build 04860477) compiled at 2022-10-28 20:04:35 commit 3892 last mr 8894 release) Non-SSL connection (SSL connection is recommen…

XAML标记扩展(3)

一、RelativeSource属性 我们进行Bingding时&#xff0c;如果明确知道数据源的Name&#xff0c;就能用Source或者ElementName进行绑定&#xff0c;但是有时候我们需要绑定的数据源可能没有明确的Name&#xff0c;此时我们就需要利 用Bingding的RelativeSource进行绑定&#xf…

虚拟数字人/直播/捏脸/3D/metahuman 实时人脸动作捕捉 开发笔记

拍照生成数字人 流程 手机&#xff08;iphone xr以上&#xff09;拍照&#xff08;脸部&#xff09;&#xff0c;导入到unrealmetahuman做数字人 【中文】从0开始捏一个自己的虚拟人&#xff0c;手机扫描到MetaHuman做一个自己的虚拟人_哔哩哔哩_bilibili 涉及APP iphone …

[附源码]java毕业设计校园兼职招聘系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

YUV图像基础知识

概念 YUV和RGB的功能类似&#xff0c;都是用来表示图像色彩的。但是对于 YUV 所表示的图像&#xff0c;Y 和 UV 分量是分离的。如果只有 Y 分量而没有 UV 分离&#xff0c;那么图像表示的就是黑白图像。彩色电视机采用的就是 YUV 图像&#xff0c;解决与和黑白电视机的兼容问题…

swift枚举(二)

swift枚举(一) No-payload enums 布局比较简单&#xff0c;也好理解&#xff0c;接下来看看 Single-payload enums Single-payload enums enum IFLEnum {case test_one(Bool)case test_twocase test_threecase test_four}print(MemoryLayout<IFLEnum>.size)print(Memor…

Vue事件处理器:事件绑定基础、事件修饰符:stop、prevent、capture、self、once;

先看代码&#xff1a; <body><div id"box">{{count}}<button click"handleAdd1()">add1</button><button click"handleAdd2">add2</button></div><script>new Vue({el: "#box",dat…

关于电脑使用的实用技巧

电脑几乎是我们每天都会用到的工具&#xff0c;那么电脑的使用技巧你知道多少呢&#xff1f;今天&#xff0c;我来为大家整理了几个常用的技巧&#xff0c;希望对大家的工作或学习效率有所帮助。 技巧一&#xff1a;快速查找文档按Windows E键打开电脑中的资源管理器&#xff0…

[附源码]SSM计算机毕业设计个性化新闻推荐系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

记一次神奇的 pipe 错误

文章目录1. 写在最前面2. 问题原因3. 解决问题3.1 CAP 的历史说明3.2 CAP 拆分的能力集合说明3.3 如何知道某个程序的能力集合3.3.1 查看只能写入 4096B 大小的程序能力位图3.3.2 查看能写入 65536B 大小的能力位图3.3.3 比较两个能力位图3.3.4 为 pod 增加 CAP_SYS_RESOURCE 的…

数字信号处理-4-三角函数合成与傅里叶级数

1 三角函数合成 函数正交&#xff08;数字信号处理-3-函数的正交&#xff09;&#xff0c;那它们相互之间无法通过组合得出对方的表达式&#xff0c;如&#xff1a;sinx 与 cosx 正交&#xff0c;acosnx 是无法表示 sinx 的。相互正交的各类三角函数是制作许多波形的基本单位。…

KT148A语音芯片按键版本一对一触发播放功能描述_V4

目录 一、简介 KT148A语音芯片--按键版本&#xff0c;支持3个IO口一对一触发 。同时也支持用户自己更换芯片内部的声音文件&#xff0c;方法&#xff0c;参考我们另外一份文档的描述“20220704_KT148A芯片自己更换声音的方法V3”。请留意&#xff0c;需要样品联系客服&#xf…