day41|● 343. 整数拆分 ● 96.不同的二叉搜索树

文章介绍了两种使用递归和动态规划(dp)解决的算法问题:一是找到将整数n拆分为若干个正整数乘积最大的方式,二是计算不同结点数的二叉搜索树的个数。通过递归五部曲——推导dp数组、递推公式、初始化、递推顺序和举例,详细解释了解题思路和过程。

题目链接:343. 整数拆分

1.代码

暴力做法:n前进行组合搜索得出二维数组result存放结果,然后对里面的元素进行乘积,谁最大就是结果

2.递归做法

class Solution {
public:
    int integerBreak(int n) {
        vector<int>f(n + 5, 0);
        f[2] = 1;
        for (int i = 3; i <= n; i++) {
            for (int j = 1; j <= i / 2; j++) {
                f[i] =max(f[i], max(j * (i - j), j * f[i - j]));
            }
        }
        return f[n];
    }
};

2.递归五部曲

1.推导dp数组和其中的含义

题目为求拆分n的乘积最大值,这就是dp数组的含义

2.推导递推公式

f[i]等于什么呢?由题目可以看出,我们先来看后面几个,因为题目没有说,我们不知道前几步到底在哪,k必须大于或等于2,我们就可以看成f[i]是由2个,3个,4个,i个构成的,我们可以先定义一个变量j遍历,确定第一个元素

如果是2个时,f[i] = j *(i - j)

如果是更多个,f[i] = j * f[i - j];

所以我们可以确定这两种类型可以确定f[i]

因为是对j进行for循环,我们需要对每个j求,最后的最大值就是结果

f[i] = max(f[i], max(j * (i - j), j * f[i - j]))

3.确定初始参数值

我们可以确定必须要分成两份,f[2] = 1

4.确定递推顺序

因为我们需要求f[n],所以最外面一层是对每个i进行求最大值,直到求到n

第二层就是对每个i求最大值的逻辑,确定第一个参数,其他参数就能够确定了

5.举例推导dp数组

可以自己模拟前面几个看一看正确不正确


题目链接:96. 不同的二叉搜索树

1.代码

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

 2.递归五部曲

1.确定dp数组和其下标含义

题目求结点数位n的二叉搜索树的个数,dp[i]就是求结点数位i的搜索树个数

2.确定递推公式

怎么求出的二叉搜索树的个数呢?

如3,对每个结点都有是根节点的可能性,根节点可以是1,2,3。当结点为1时,左子树必须比1小,说明左子树个数为0,右子树为2.  当结点为2时,左右子树各一个结点。  当根结点为3时,左边有两个,右边没有,可以推导f[3] = f[0]f[2] + f[1][1] + f[2][0],就是i为根,比i小的个数*比i大的个数就是以i为根节点的二叉搜索树个数

f[i]:i个结点搜索树的个数,--求出f[i]必须求出从1到i为根结点的二叉搜索树的个数和

3.初始化

介于推导地推公式需要f[0]=1,为0不能,f[1]=1,f[2] =2,其实可以不写这么多,用到哪个写哪个

4.确定递推顺序

因为需要求出f[n]前必须求出f[1-n]所以外面一层循环是求每一个f[i],里面的循环是有i个结点后以j为根结点的个数,对其求和就是i个结点的二叉搜索树的个数了

5.距离说明dp数组

 

可以自己距离前面几个模拟一下

### JavaScript 中用于验证日期字段有效性的条件逻辑解释 在 JavaScript 中,验证日期字段(如 `day`、`month` 和 `year`)是否有效的逻辑通常涉及以下几个关键点: #### 1. 检查字段是否存在 代码首先检查表单中是否存在对应的日期字段(如 `day`、`month` 和 `year`)。如果某个字段不存在,则跳过对该字段的验证[^1]。 ```javascript if (varform.elements[elementName + '[day]'] && varform.elements[elementName + '[day]'].value < 1) { // 验证 day 字段的有效性 } ``` #### 2. 检查字段值是否满足最小值要求 对于每个字段(`day`、`month` 和 `year`),代码会检查其值是否满足特定的最小值要求。例如: - `day` 的值必须大于等于 1。 - `month` 的值必须大于等于 1。 - `year` 的值必须大于等于 1902。 ```javascript if (varform.elements[elementName + '[day]'].value < 1 || varform.elements[elementName + '[month]'].value < 1 || varform.elements[elementName + '[year]'].value < 1902) { // 如果任意一个字段值不满足要求,则认为无效 } ``` #### 3. 标记无效字段 如果某个字段的值不满足要求,代码会将其标记为无效,通过向该字段的 `className` 属性追加 `invalid` 样式类[^1]。 ```javascript if (varform.elements[elementName + '[day]'].value < 1) { varform.elements[elementName + '[day]'].className += ' invalid'; } ``` #### 4. 提示用户并终止表单提交 如果检测到任何无效字段,代码会弹出提示信息,并阻止表单的提交操作[^1]。 ```javascript alert(acymailing['validFields' + formName][i]); return false; ``` --- ### 示例代码解析 以下是一个完整的示例代码,展示如何验证日期字段的有效性: ```javascript function validateDateFields(varform, elementName, acymailing, formName, i) { if ( (varform.elements[elementName + '[day]'] && varform.elements[elementName + '[day]'].value < 1) || (varform.elements[elementName + '[month]'] && varform.elements[elementName + '[month]'].value < 1) || (varform.elements[elementName + '[year]'] && varform.elements[elementName + '[year]'].value < 1902) ) { if (varform.elements[elementName + '[day]'] && varform.elements[elementName + '[day]'].value < 1) { varform.elements[elementName + '[day]'].className += ' invalid'; // 标记 day 字段为无效 } if (varform.elements[elementName + '[month]'] && varform.elements[elementName + '[month]'].value < 1) { varform.elements[elementName + '[month]'].className += ' invalid'; // 标记 month 字段为无效 } if (varform.elements[elementName + '[year]'] && varform.elements[elementName + '[year]'].value < 1902) { varform.elements[elementName + '[year]'].className += ' invalid'; // 标记 year 字段为无效 } alert(acymailing['validFields' + formName][i]); // 提示用户 return false; // 阻止表单提交 } return true; // 如果所有字段都有效,则允许提交 } ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值