343. 整数拆分
给定一个正整数 n
,将其拆分为 k
个 正整数 的和( k >= 2
),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积
思路:我们可以遍历正整数i之前的所有 j 对于正整数 i 可以拆解成 j + i-j ,那么有以下选择,第一个是 i -j 不再拆分,那么此时的乘积就是 j * (i-j),如果继续拆分,那么就是 j * dp[ i- j]。遍历时比较这两者与当前dp[i],取三者最大值。
class Solution:
def integerBreak(self, n: int) -> int:
dp = [0] * (n + 1) # 创建一个大小为n+1的数组来存储计算结果
dp[2] = 1 # 初始化dp[2]为1,因为当n=2时,只有一个切割方式1+1=2,乘积为1
# 从3开始计算,直到n
for i in range(3, n + 1):
# 遍历所有可能的切割点,遍历到 一半就可以,后面的跟前面是对称的
for j in range(1, i // 2 + 1):
# 计算切割点j和剩余部分(i-j)的乘积,并与之前的结果进行比较取较大值
dp[i] = max(dp[i], (i - j) * j, dp[i - j] * j)
return dp[-1] # 返回最终的计算结果
给你一个整数 n
,求恰由 n
个节点组成且节点值从 1
到 n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
思路:假设有n个数字,那么就有n个数可以作为头节点。假设该头节点为 i ,此时,头节点左侧的数有 i - 1 个,右侧的节点有n- i 个。各自的节点对应着 由 i -1 个节点组成的二叉搜索树和n-i个节点组成的二叉搜索树。那么它们各自的种树的积就是nge节点时的二叉搜索树的种数。因此,递推公式为:dp[i] += dp[j - 1] * dp[i - j]; ,j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量。dp[i] 的定义为有i个节点时的二叉搜索树的种数。
class Solution:
def numTrees(self, n: int) -> int:
dp = [0] * (n + 1)
dp[0] = 1 # 当n为0时,只有一种情况,即空树,所以dp[0] = 1
for i in range(1, n + 1): # 遍历从1到n的每个数字
for j in range(1, i + 1): # 对于每个数字i,计算以i为根节点的二叉搜索树的数量
dp[i] += dp[j - 1] * dp[i - j]
return dp[n]