給定乙個正整數 n,將其拆分為至少兩個正整數的和,並使這些整數的乘積最大化。 返回你可以獲得的最大乘積。
動態規劃
1、對於的正整數 n,當 n≥2 時,可以拆分成至少兩個正整數的和。
2、令 kk是拆分出的第乙個正整數,則剩下的部分是 n-k,n-k 可以不繼續拆分,或者繼續拆分成至少兩個正整數的和。
3、由於每個正整數對應的最大乘積取決於比它小的正整數對應的最大乘積,因此可以使用動態規劃求解。
4、開陣列
建立陣列 dp,其中 dp[i] 表示將正整數 i 拆分成至少兩個正整數的和之後,這些正整數的最大乘積。
5、初始化
0 不是正整數,1 是最小的正整數,0 和 1 都不能拆分,因此dp[0]=dp[1]=0。
6、建立狀態轉移方程
當 i≥2 時,假設對正整數i 拆分出的第乙個正整數是 j(1≤j將 i 拆分成 j和 i−j 的和,且i−j不再拆分成多個正整數,此時的乘積是j×(i−j);
將 i 拆分成 j和i−j 的和,且i−j繼續拆分成多個正整數,此時的乘積是j×dp[i−j]。
7、因此,當 j 固定時,有dp[i]=max(j×(i−j),j×dp[i−j])。由於 j 的取值範圍是 1 到 i−1,需要遍歷所有的 j得到 dp[i] 的最大值
狀態轉移方程為
8、最終得到 dp[n] 的值即為將正整數 n 拆分成至少兩個正整數的和之後,這些正整數的最大乘積。
**
class
solution
:def
integerbreak
(self, n:
int)
->
int:
#開陣列,初始化
dp =[0
]*(n +1)
#建立狀態轉移方程
for i in
range(2
, n +1)
:for j in
range
(i):
dp[i]
=max
(dp[i]
, j *
(i - j)
, j * dp[i - j]
)return dp[n]
時間複雜度:o(n^ 2 ),其中 n 是給定的正整數。
空間複雜度:o(n),其中 n 是給定的正整數。建立乙個陣列dp,其長度為 n+1。
每日一題 力扣演算法 整數拆分
給定乙個正整數 n,將其拆分為至少兩個正整數的和,並使這些整數的乘積最大化。返回你可以獲得的最大乘積。示例 1 輸入 2 輸出 1 解釋 2 1 1,1 1 1。示例 2 輸入 10 輸出 36 解釋 10 3 3 4,3 3 4 36。說明 你可以假設 n 不小於 2 且不大於 58。第一種方法 ...
每日一題 力扣 計畫
98 驗證二叉搜尋樹 問題給定乙個二叉樹,判斷其是否是乙個有效的二叉搜尋樹。假設乙個二叉搜尋樹具有如下特徵 1.節點的左子樹只包含小於當前節點的數。2.節點的右子樹只包含大於當前節點的數。3.所有左子樹和右子樹自身必須也是二叉搜尋樹。示例 1 輸入 2 1 3 輸出 true示例2 輸入 5 1 4...
力扣每日一題 6 14
1300 轉變陣列後最接近目標值的陣列和 給你乙個整數陣列 arr 和乙個目標值 target 請你返回乙個整數 value 使得將陣列中所有大於 value 的值變成 value 後,陣列的和最接近 target 最接近表示兩者之差的絕對值最小 如果有多種使得和最接近 target 的方案,請你返...