Day 41
343. 整數拆分
一個是j * dp[i - j],相當于是拆分(i - j),對這個拆分不理解的話,可以回想dp數組的定義。
dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j});
class Solution:def integerBreak(self, n: int) -> int:dp = [0] * (n + 1)dp[2] = 1for i in range(3, n + 1):for j in range(1, i // 2 + 1):dp[i] = max(dp[i], (i - j) * j, dp[i - j] * j)return dp[n]
class Solution {public int integerBreak(int n) {//dp[i] 為正整數 i 拆分后的結果的最大乘積int[] dp = new int[n+1];dp[2] = 1;for(int i = 3; i <= n; i++) {for(int j = 1; j <= i-j; j++) {// 這里的 j 其實最大值為 i-j,再大只不過是重復而已,//并且,在本題中,我們分析 dp[0], dp[1]都是無意義的,//j 最大到 i-j,就不會用到 dp[0]與dp[1]dp[i] = Math.max(dp[i], Math.max(j*(i-j), j*dp[i-j]));// j * (i - j) 是單純的把整數 i 拆分為兩個數 也就是 i,i-j ,再相乘//而j * dp[i - j]是將 i 拆分成兩個以及兩個以上的個數,再相乘。}}return dp[n];}
}
96.不同的二叉搜索樹
dp[3],就是 元素1為頭結點搜索樹的數量 + 元素2為頭結點搜索樹的數量 + 元素3為頭結點搜索樹的數量
元素1為頭結點搜索樹的數量 = 右子樹有2個元素的搜索樹數量 * 左子樹有0個元素的搜索樹數量
元素2為頭結點搜索樹的數量 = 右子樹有1個元素的搜索樹數量 * 左子樹有1個元素的搜索樹數量
元素3為頭結點搜索樹的數量 = 右子樹有0個元素的搜索樹數量 * 左子樹有2個元素的搜索樹數量
有2個元素的搜索樹數量就是dp[2]。
有1個元素的搜索樹數量就是dp[1]。
有0個元素的搜索樹數量就是dp[0]。
所以dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2]
class Solution:def numTrees(self, n: int) -> int:dp = [0] * (n + 1)dp[0] = 1for i in range(1, n + 1):for j in range(1, i + 1):dp[i] += dp[j - 1] * dp[i - j]return dp[n]
class Solution {public int numTrees(int n) {//初始化 dp 數組int[] dp = new int[n + 1];//初始化0個節點和1個節點的情況dp[0] = 1;dp[1] = 1;for (int i = 2; i <= n; i++) {for (int j = 1; j <= i; j++) {//對于第i個節點,需要考慮1作為根節點直到i作為根節點的情況,所以需要累加//一共i個節點,對于根節點j時,左子樹的節點個數為j-1,右子樹的節點個數為i-jdp[i] += dp[j - 1] * dp[i - j];}}return dp[n];}
}