LeetCode刷题day41|343.整数拆分、96.不同的二叉搜索树

文章目录

  • 一、343.整数拆分
  • 二、96.不同的二叉搜索树
    • 1. 递归方式
    • 2.非递归方式

一、343.整数拆分

注意的点:

  1. 递推公式是寻找 分成2个数 和 分成3个及以上数 这两种情况的最大值。即 Math.max(j * (i - j), j * dp[i-j])
  2. 注意在取得上述最大值后,还要与之前循环得到的dp[i] 进行比较。这个dp[i]是之前不同j的情况下的最大取值。

以下是代码部分:

	//代码随想录代码
    public int integerBreak(int n) {

        //定义dp数组
        int[] dp = new int[n+1];

        //递推公式

        //初始化
        dp[2] = 1;

        //遍历
        //i从3开始,j从1开始
        for (int i = 3; i < dp.length; i++) {
            for (int j = 1; j < i ;j++) {
                //这里之所以有dp[i],是因为要记录前边的值。因为每次同一个 j 只比较了 j*(i-j)、j*dp[i-j],这是还需要比较前边得出的最大的dp[i]
                dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i-j]));
            }
        }

        return dp[n];
    }

二、96.不同的二叉搜索树

其实递归方式和非递归方式的思路一样,都用的同一个递推公式: dp[i] += dp[j - 1] * dp[i - j]; ,j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量。

1. 递归方式

这里用哈希表来记录n对应的种类数,避免重复计算,效率提升明显。

	//LeetCode递归方法
    Map<Integer,Integer> map = new HashMap<>();

    public int numTrees3(int n) {

        if( n == 0 || n==1)
            return 1;

        if(map.containsKey(n))
            return map.get(n);

        int count = 0;
        for (int i = 1; i <= n; i++) {

            int left = numTrees3(i-1);

            int right = numTrees3(n - i);

            //这里是count +=
            count += left*right;
        }

        map.put(n, count);

        return count;
    }

2.非递归方式

//每一步都是在前一步的基础上 加 叶子节点*2,可以用动态规划
    public int numTrees(int n) {

        int[] dp = new int[n+1];

        //dp[0]要设置成1,因为要乘以dp[i]
        dp[0] = 1;
        dp[1] = 1;

        for (int i = 2; i < dp.length; i++) {
            for (int j = 1; j <= i ; j++) {
                //这里注意是dp[j-1]而不是dp[j]
                dp[i] += dp[j-1]*dp[i-j];
            }
        }
        return dp[n];
    }

你可能感兴趣的:(LeetCode,leetcode,算法,职场和发展)