首页 > 编程语言 >【算法训练营day41】LeetCode343. 整数拆分 LeetCode96. 不同的二叉搜索树

【算法训练营day41】LeetCode343. 整数拆分 LeetCode96. 不同的二叉搜索树

时间:2023-02-07 14:34:16浏览次数:55  
标签:LeetCode343 元素 LeetCode96 二叉 int 搜索 day41 节点 dp

LeetCode343. 整数拆分

题目链接:343. 整数拆分

独上高楼,望尽天涯路

一开始想到的是用数学证明化简的方法,每次拆成尽可能多的3,最后剩下的是2或4,此时相乘最大。

class Solution {
public:
    int integerBreak(int n) {
        if (n == 2) return 1;
        if (n == 3) return 2;
        if (n == 4) return 4;
        int result = 1;
        while (n > 4) {
            result *= 3;
            n -= 3;
        }
        result *= n;
        return result;
    }
};

慕然回首,灯火阑珊处

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

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

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

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

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

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

LeetCode96. 不同的二叉搜索树

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

独上高楼,望尽天涯路

感觉是一道很难想的题,没有太好的思路。

慕然回首,灯火阑珊处

很巧妙的思路,需要举例并且画图才能推导出来。

首先,因为只需要返回不同二叉搜索树的种数,所以我们不太需要在意节点具体的值(感觉这是题目的障眼法),只需要知道它们是互不相同节点值的就行,顺着这条思路,我们就可以知道节点值为1,2,3组成的不同二叉搜索树的种数和节点值为43,154,6546组成的种数是一样的,这是因为我们只在乎相对大小!

其次,对于任意整数n,不同的二叉搜索树的数量都可以分解为:元素1为头节点搜索树的数量 + 元素2为头节点搜索树的数量 + ... + 元素n为头节点搜索树的数量。

元素1为头节点搜索树的数量 = 右子树有n - 1个元素的搜索树数量 * 左子树有1 - 1个元素的搜索树数量

元素2为头节点搜索树的数量 = 右子树有n - 2个元素的搜索树数量 * 左子树有2 - 1个元素的搜索树数量

...

元素n为头节点搜索树的数量 = 右子树有n - n个元素的搜索树数量 * 左子树有n - 1个元素的搜索树数量

因为我们只在乎相对大小,对于右子树有n - 1个元素的搜索树数量,我们不需要去细想有哪些节点值,我们只需要知道它们是互不相同的,这个数量和节点值从1到n - 1的搜索树数量其实是一样的!

所以,假设dp[i]表示的是由i个节点组成且节点值为1到i的互不相同的二叉搜索树的种数,上文中“右子树有n - 1个元素的搜索树数量”就可以表示为dp[i - 1],递推公式即为dp[i] += dp[i - j] * dp[j - 1]。

空节点也是一棵二叉搜索树,所以初始化dp[0] = 1。

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

标签:LeetCode343,元素,LeetCode96,二叉,int,搜索,day41,节点,dp
From: https://www.cnblogs.com/BarcelonaTong/p/17098281.html

相关文章

  • day41_0501.二叉搜索树中的众数
    我的思路递归法如果是二叉搜索树如果不是二叉搜索树迭代法我的思路classSolution{private:unordered_map<int,int>map;vector<int>res......
  • 代码随想录Day41
    LeetCode538.把二叉搜索树转化为累加树给出二叉搜索树的根节点,该树的节点值各不相同,请你将其转换为累加树(GreaterSumTree),使每个节点node 的新值等于原树中大于或等......
  • LeetCode962. Maximum Width Ramp
    题意给一个序列,求其中最大的j-i,满足i<j且num[i]<=nums[j]方法单调栈代码classSolution{public:intmaxWidthRamp(vector<int>&A){stack<int......
  • 进入python的世界_day41_数据库——视图、触发器、事务、存储过程、函数、索引(未搞定,
    一、在pycharm中运行mysql编写登录注册功能1.注册​ 先用navicat建立一张表,比如就ID主键,姓名,密码这三个字段建立表#pycharm代码实操#1.还是先导入模块,创建pymysql的......
  • day41MySQl基础(04)
    SQL语句查询关键字selectfromwheregroupbyhavingdistinctorderbylimitregexp多表查询的两种方式子查询连表操作报错及作业讲解报错 1.粗心大意单词拼......
  • day41MySQL基础(3)
    目录无符号、零填充非空默认值唯一值主键自增外键前戏关系的判断一对多关系外键字段的建立多对多关系一对一关系无符号、零填充unsigned idintunsignedzerofill id......
  • leetcode343-数拆分。还需要继续琢磨
    343.整数拆分 这道题的关键点在于下面这两个式子。比如要计算dp【10】,就逐个比较1*dp【9】,2*dp【8】,3*dp【7】,还有1*9,2*8,3*7,才考虑了所有的情况如果使用dp[i]=max(d......
  • day41
    web项目web项目配置tomcatweb项目:就是将项目的服务端部署在服务器上,通过浏览器进行网络传出数据,并且从服务器得到响应,在浏览器上显示数据的项目;通常我们看见的网页......
  • 代码随想录day41 | 343. 整数拆分 96. 不同的二叉搜索树
    343.整数拆分题目|文章思路一个动态规划问题最重要的就是找到递推公式,找到递推公式,整个题就已经解出来了。这道题看到时会想分成几份比较好,等于10时与之前的数有什么......
  • 前端Promise-Day41
    Promise的API:Promise构造函数:Promise(executor{})executor函数:执行器(resolve,reject)=>{}resolve函数:内部定义成功时执行的函数reject函数:内部定义失败时执行的函数e......