算法训练第四十一天|343. 整数拆分、96. 不同的二叉搜索树

2023-12-18 22:42:44

343. 整数拆分:

题目链接
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

示例 :

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

解答:

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

算法总结:

本题主要思路在于拆分的思路,j*(i - j) 是单纯的把整数拆分为两个数相乘,而 j×dp[i - j]是拆分成两个以及两个以上的个数相乘。所以关于dp的推导公式就是 dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));通过两个for循环可以求出最终值

96. 不同的二叉搜索树:

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

示例 :
在这里插入图片描述

输入:n = 3
输出:5

解答:

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

算法总结:

由题我们可以想到一个结点他的左右子树分布情况是一样的(如1为头结点,他的子树就是两个结点的情况),所以求n为3的情况实际上就是头结点1+头结点2+头结点3的情况,我们可以发现头结点1=左子树0结点* 右子树2结点,按照这个我们得出 dp[i] += dp[j - 1]*dp[i - j]这个推导

文章来源:https://blog.csdn.net/lenwu222/article/details/135071944
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。