力扣(动态规划)-343整数拆分;96不同的二叉搜索树

2024-08-25 01:04

本文主要是介绍力扣(动态规划)-343整数拆分;96不同的二叉搜索树,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 整数拆分

题目:

给定⼀个正整数 n,将其拆分为⾄少两个正整数的和,并使这些整数的乘积最⼤化。 返回你可以获得的最⼤乘积。

示例 1:

输⼊: 2

输出: 1

解释: 2 = 1 + 1, 1 × 1 = 1。

示例 2:

输⼊: 10

输出: 36

解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。

提示:

  • 2 <= n <= 58

说明: 你可以假设 n 不⼩于 2 且不⼤于 58。

动态规划五部曲:

  • 1使用一个一维(二维)dp数组来保存递归结果:

由于我们要求的是对任意的整数n找到其规定条件下的最大乘积,所以首先想到:

状态转移方程dp[i]表示数字i的最大乘积

  • 2.确定递推公式

要找到dp[i]的最大乘积,可以将dp[i]划分为一个不会再被划分的数j,和一个会被划分m次但是总和为 (i-j)的数.

此时由于j不会再被划分,所以要使dp[i]最大,则 就要对(i-j)进行拆分使得拆分后的几个整数的乘积最大,即dp[i-j]。

所以

dp[i]的最大乘积=j * dp[i-j]

由于j是一个不确定的数,所以需要对j进行遍历,确定j为某个值时使得j*dp[i-j]最大

上面我们就解释了为什么dp[i]=j*dp[i-j],但是有一个容易被忽略的问题:

题目我们的dp[i]是由至少两个整数相乘得到的。那么同样的dp[i-j]也是由至少两个整数组成的。所以这里遗漏了一种情况:若是i-j不进行划分时得到dp[i]的最大值,那么dp[i]=j*(i-j)

综上所诉,我们的递推公式应该是dp[i]=max(   j * dp[i-j],   j*(i-j)  )

  • 3.Dp数组如何初始化

由于题目中最小的能够进行划分的数是2,所以严格的定义来说,我们只需要从2开始初始化递推函数:dp[2]=1;  (1*1=1)

但此时要注意,递推公式dp[i]=j*dp[i-j]中的i-j要保证大于等于2

  • 4.确定遍历序列(eg:不同路径)

从递推公式dp[i]=j*dp[i-j]可以看出后面的结果是由前面i-j推导出来的,所以i⼀定是从小到大遍历,先有dp[i - j]再有dp[i]

  • 5.举例推导递推公式,避免错误
class Solution {
public:int integerBreak(int n) {vector<int>dp(n+1,0);dp[2]=1;for(int i=3;i<=n;i++){//dp[i]中的ifor(int j=1;j<=i-2;j++){//要保证dp[i-j]中的i-j>=2int t=max(j*dp[i-j], j*(i-j));if(t>dp[i])dp[i]=t;}}return dp[n];}
};

96不同的二叉搜索树

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

示例 1:

输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

提示:

  • 1 <= n <= 19

对于任意一个节点,它的组成是根节点,左孩子和右孩子。当一共有三个节点时,忽略节点的值,它可能的布局是:(2^0)表示最孩子两个节点,右孩子0个节点,必然有一个节点作为根节点

(2^0),(0^2)(1^1),三种可能存在的节点排序,而对于右两个节点的分支又可以有(0^1)(1^0)两个排序结构,所以有三个节点时可能存在的不同结构有2+1+2=5种

相当于有n个节点就把n进行拆分,一个作为根节点,剩余的n-1个根据结构放在左右子树上,此时就可以将情况划分为左子树有j个节点,则右子树有(n-1-j)个节点,则有递推公式dp[n]=dp[j]*[n-1-j],由于j个个数可以改变,所以j进行遍历,从0~n-1 。

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

dp[i] : 1到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[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之前节点数

的状态。

5:举例推导递推公式,避免错误

class Solution {
public:int numTrees(int n) {vector<int>dp(n+1,0);dp[0]=1;dp[1]=1;for(int i=2;i<=n;i++){for(int j=0;j<=i-1;j++){dp[i]+=dp[j]*dp[i-1-j];}}return dp[n];}
};

这篇关于力扣(动态规划)-343整数拆分;96不同的二叉搜索树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1104114

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一

PTA求一批整数中出现最多的个位数字

作者 徐镜春 单位 浙江大学 给定一批整数,分析每个整数的每一位数字,求出现次数最多的个位数字。例如给定3个整数1234、2345、3456,其中出现最多次数的数字是3和4,均出现了3次。 输入格式: 输入在第1行中给出正整数N(≤1000),在第二行中给出N个不超过整型范围的非负整数,数字间以空格分隔。 输出格式: 在一行中按格式“M: n1 n2 ...”输出,其中M是最大次数,n

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl