首页 > 编程语言 >算法学习Day41整数拆分、不同的二叉搜索树

算法学习Day41整数拆分、不同的二叉搜索树

时间:2024-01-22 23:56:15浏览次数:33  
标签:10 元素 二叉 搜索 Day41 拆分 树有 dp

Day41整数拆分、不同的二叉搜索树

By HQWQF 2024/01/22

笔记


343. 整数拆分

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

示例 1:

  • 输入: 2
  • 输出: 1
  • 解释: 2 = 1 + 1, 1 × 1 = 1。

示例 2:

  • 输入: 10
  • 输出: 36
  • 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
  • 说明: 你可以假设 n 不小于 2 且不大于 58。

动态规划

每个正整数对应的最大乘积取决于比它小的正整数对应的最大乘积

比如如果对于n=10,在提前确定10 = 3 + x(10-3)时(x(10-3)代表更多项)要得到3 * x的最大乘积,就是求x(10-3)的的最大乘积,所以我们可以使用变量遍历这里的3为各种值的情况。

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

所以对于当前的i,我们使用遍历变量为j遍历1到i/2(更大的话后面的i-j会和前面的j重复),并且通过两种渠道得到dp[i]:

一个是只拆为两个数j * (i - j) 。

一个是拆为多个数j * dp[i - j],相当于是继续拆分(i - j)。

我们可以取其中大的那个。

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

96.不同的二叉搜索树

给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?

示例:

动态规划

可以发现,对于n个元素的二叉搜索树来说,其所有的二叉搜索树结构可以分成3类,即1,2,3元素作为头节点的结构类型。

对于这3类结构,由于已经确定了头节点,该类结构的总结构数就是其左右子树的结构数和,而且其左右子树的元素数还必须符合二叉搜索树的定义,比如头节点是1的话其他元素都要在右子树上。

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

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

元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量

总结公式:

dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2]

设n为i,遍历i个元素的二叉搜索树的所有结构类型1到j(以1到j为头节点)

如果头节点是j,左边子树的元素的值必须比j小,也就是一共j-1个元素,右子树的元素的值必须比j大,一共i-j个元素。

递推公式:dp[i] += dp[j - 1] * dp[i - j] ,j为1到i间所有整数

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];
    }
};

标签:10,元素,二叉,搜索,Day41,拆分,树有,dp
From: https://www.cnblogs.com/HQWQF/p/17981418

相关文章

  • KY85 二叉树C++
    递归判断当前节点和n的关系就好了。如果小于等于n那就是存在。#include<iostream>usingnamespacestd;intcount(inti,intn){if(i>n)return0;returncount(2*i,n)+count(2*i+1,n)+1;}intmain(){intn,m;while(cin>>m>>n){if(n==0)......
  • 遍历二叉树非递归实现
    实现1.前序遍历publicvoidpreOrderNor(TreeNoderoot){if(root==null){return;}Stack<TreeNode>stack=newStack<>();stack.push(root);while(!stack.isEmpty()){TreeNodecur......
  • 二叉树面试题进阶
    二叉树面试题进阶1.二维数组存储层序遍历结果难点: 如何存储每一层的节点?根据队列节点的个数判断每一层classSolution{publicList<List<Integer>>levelOrder(TreeNoderoot){List<List<Integer>>retList=newArrayList<>();if(root==nu......
  • 实现创建二叉树
    创建二叉树1.前序遍历创建二叉树importjava.util.Scanner;//注意类名必须为Main,不要有任何packagexxx信息classTreeNode{publicTreeNodeleft;publiccharval;publicTreeNoderight;publicTreeNode(charval){this.val=......
  • 最少交换次数 置换环 LeetCode 2471. 逐层排序二叉树所需的最少操作数目
    voidMain(){ varroot=newTreeNode(1) { left=newTreeNode(3) { left=newTreeNode(7), right=newTreeNode(6) }, right=newTreeNode(2) { left=newTreeNode(5), right=newTreeNode(4) } }; varr=newSolution().Minimu......
  • 遍历二叉树
    二叉树前言二叉树的遍历主要有深度优先遍历和广度优先遍历,深度优先遍历是优先访问一个子树上的所有节点,访问的属性是竖向的,而广度优先遍历则是优先访问同一层的所有节点,访问属性是横向的。深度优先遍历深度优先遍历主要有三种顺序:前序遍历——根左右中序遍历——左根......
  • 31_修剪二叉搜索树
    669.修剪二叉搜索树给你二叉搜索树的根节点root,同时给定最小边界low和最大边界high。通过修剪二叉搜索树,使得所有节点的值在[low,high]中。修剪树不应该改变保留在树中的元素的相对结构(即,如果没有被移除,原有的父代子代关系都应当保留)。可以证明,存在唯一的答案。所......
  • 30_删除二叉搜索树中的节点
    450.删除二叉搜索树中的节点给定一个二叉搜索树的根节点root和一个值key,删除二叉搜索树中的key对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。一般来说,删除节点可分为两个步骤:首先找到需要删除的节点;如果找到了,删除它。示例1:......
  • 每日一题 2024-1-20 按分隔符拆分字符串
    1.题目(1239)原题链接给你一个字符串数组\(words\)和一个字符\(separator\),请你按\(separator\)拆分\(words\)中的每个字符串。返回一个由拆分后的新字符串组成的字符串数组,不包括空字符串。注意\(separator\)用于决定拆分发生的位置,但它不包含在结果字符串中。拆分......
  • 二叉树 - 二叉树入门题
    二叉树入门题1.判断两颗树是否相同classSolution{publicbooleanisSameTree(TreeNodep,TreeNodeq){//如何判断两颗树是否相同?根相同+左右子树相同//如何判断根相同?结构+值相同if(p==null&&q!=null||p!=null&&......