@@ -53,15 +53,22 @@ tags:
5353
5454### 方法一:动态规划
5555
56- 我们定义 $dp [ i] $ 表示正整数 $n$ 能获得的最大乘积,初始化 $dp [ 1] = 1$。答案即为 $dp [ n] $。
56+ 我们定义 $f [ i] $ 表示正整数 $i$ 拆分后能获得的最大乘积,初始时 $f [ 1] = 1$。答案即为 $f [ n] $。
5757
58- 状态转移方程为:
58+ 考虑 $i$ 最后拆分出的数字 $j$,其中 $j \in [ 1, i)$。对于 $i$ 拆分出的数字 $j$,有两种情况:
59+
60+ 1 . 将 $i$ 拆分成 $i - j$ 和 $j$ 的和,不继续拆分,此时乘积为 $(i - j) \times j$;
61+ 2 . 将 $i$ 拆分成 $i - j$ 和 $j$ 的和,继续拆分,此时乘积为 $f[ i - j] \times j$。
62+
63+ 因此,我们可以得到状态转移方程:
5964
6065$$
61- dp [i] = max(dp [i], dp [i - j] \times j, (i - j) \times j) \quad (j \in [0, i))
66+ f [i] = \ max(f [i], f [i - j] \times j, (i - j) \times j) \quad (j \in [0, i))
6267$$
6368
64- 时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为正整数 $n$。
69+ 最后返回 $f[ n] $ 即可。
70+
71+ 时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为给定的正整数。
6572
6673<!-- tabs:start -->
6774
7077``` python
7178class Solution :
7279 def integerBreak (self , n : int ) -> int :
73- dp = [1 ] * (n + 1 )
80+ f = [1 ] * (n + 1 )
7481 for i in range (2 , n + 1 ):
7582 for j in range (1 , i):
76- dp [i] = max (dp [i], dp [i - j] * j, (i - j) * j)
77- return dp [n]
83+ f [i] = max (f [i], f [i - j] * j, (i - j) * j)
84+ return f [n]
7885```
7986
8087#### Java
8188
8289``` java
8390class Solution {
8491 public int integerBreak (int n ) {
85- int [] dp = new int [n + 1 ];
86- dp [1 ] = 1 ;
92+ int [] f = new int [n + 1 ];
93+ f [1 ] = 1 ;
8794 for (int i = 2 ; i <= n; ++ i) {
8895 for (int j = 1 ; j < i; ++ j) {
89- dp [i] = Math . max(Math . max(dp [i], dp [i - j] * j), (i - j) * j);
96+ f [i] = Math . max(Math . max(f [i], f [i - j] * j), (i - j) * j);
9097 }
9198 }
92- return dp [n];
99+ return f [n];
93100 }
94101}
95102```
@@ -100,14 +107,14 @@ class Solution {
100107class Solution {
101108public:
102109 int integerBreak(int n) {
103- vector<int > dp (n + 1);
104- dp [ 1] = 1;
110+ vector<int > f (n + 1);
111+ f [ 1] = 1;
105112 for (int i = 2; i <= n; ++i) {
106113 for (int j = 1; j < i; ++j) {
107- dp [ i] = max(max(dp [ i] , dp [ i - j] * j) , (i - j) * j);
114+ f [ i] = max({f [ i] , f [ i - j] * j, (i - j) * j} );
108115 }
109116 }
110- return dp [ n] ;
117+ return f [ n] ;
111118 }
112119};
113120```
@@ -116,28 +123,28 @@ public:
116123
117124```go
118125func integerBreak(n int) int {
119- dp := make([]int, n+1)
120- dp [1] = 1
126+ f := make([]int, n+1)
127+ f [1] = 1
121128 for i := 2; i <= n; i++ {
122129 for j := 1; j < i; j++ {
123- dp [i] = max(max(dp [i], dp [i-j]*j), (i-j)*j)
130+ f [i] = max(max(f [i], f [i-j]*j), (i-j)*j)
124131 }
125132 }
126- return dp [n]
133+ return f [n]
127134}
128135```
129136
130137#### TypeScript
131138
132139``` ts
133140function integerBreak(n : number ): number {
134- let dp = new Array (n + 1 ).fill (1 );
141+ const f = Array (n + 1 ).fill (1 );
135142 for (let i = 3 ; i <= n ; i ++ ) {
136143 for (let j = 1 ; j < i ; j ++ ) {
137- dp [i ] = Math .max (dp [i ], j * (i - j ), j * dp [i - j ]);
144+ f [i ] = Math .max (f [i ], j * (i - j ), j * f [i - j ]);
138145 }
139146 }
140- return dp . pop () ;
147+ return f [ n ] ;
141148}
142149```
143150
@@ -146,24 +153,69 @@ function integerBreak(n: number): number {
146153``` rust
147154impl Solution {
148155 pub fn integer_break (n : i32 ) -> i32 {
149- if n < 4 {
150- return n - 1 ;
156+ let n = n as usize ;
157+ let mut f = vec! [0 ; n + 1 ];
158+ f [1 ] = 1 ;
159+ for i in 2 ..= n {
160+ for j in 1 .. i {
161+ f [i ] = f [i ]. max (f [i - j ] * j ). max ((i - j ) * j );
162+ }
163+ }
164+ f [n ] as i32
165+ }
166+ }
167+ ```
168+
169+ #### JavaScript
170+
171+ ``` js
172+ /**
173+ * @param {number} n
174+ * @return {number}
175+ */
176+ var integerBreak = function (n ) {
177+ const f = Array (n + 1 ).fill (1 );
178+ for (let i = 2 ; i <= n; ++ i) {
179+ for (let j = 1 ; j < i; ++ j) {
180+ f[i] = Math .max (f[i], f[i - j] * j, (i - j) * j);
181+ }
182+ }
183+ return f[n];
184+ };
185+ ```
186+
187+ #### C#
188+
189+ ``` cs
190+ public class Solution {
191+ public int IntegerBreak (int n ) {
192+ int [] f = new int [n + 1 ];
193+ f [1 ] = 1 ;
194+ for (int i = 2 ; i <= n ; ++ i ) {
195+ for (int j = 1 ; j < i ; ++ j ) {
196+ f [i ] = Math .Max (Math .Max (f [i ], f [i - j ] * j ), (i - j ) * j );
197+ }
151198 }
152- let count = (n - 2 ) / 3 ;
153- (3i32 ). pow (count as u32 ) * (n - count * 3 )
199+ return f [n ];
154200 }
155201}
156202```
157203
158204#### C
159205
160206``` c
207+ #define max (a, b ) (((a) > (b)) ? (a) : (b))
208+
161209int integerBreak (int n) {
162- if (n < 4) {
163- return n - 1;
210+ int* f = (int* ) malloc((n + 1) * sizeof(int));
211+ f[ 1] = 1;
212+ for (int i = 2; i <= n; ++i) {
213+ f[ i] = 0;
214+ for (int j = 1; j < i; ++j) {
215+ f[ i] = max(f[ i] , max(f[ i - j] * j, (i - j) * j));
216+ }
164217 }
165- int count = (n - 2) / 3;
166- return pow(3, count) * (n - count * 3);
218+ return f[ n] ;
167219}
168220```
169221
@@ -175,7 +227,7 @@ int integerBreak(int n) {
175227
176228### 方法二:数学
177229
178- 当 $n \lt 4$ 时,$n$ 不能拆分成至少两个正整数的和 ,因此 $n - 1$ 是最大乘积。当 $n \ge 4$ 时,我们尽可能多地拆分 $3$,当剩下的最后一段为 $4$ 时,我们将其拆分为 $2 + 2$,这样乘积最大。
230+ 当 $n \lt 4$ 时,由于题目要求至少拆分成两个整数 ,因此 $n - 1$ 是最大乘积。当 $n \ge 4$ 时,我们尽可能多地拆分 $3$,当剩下的最后一段为 $4$ 时,我们将其拆分为 $2 + 2$,这样乘积最大。
179231
180232时间复杂度 $O(1)$,空间复杂度 $O(1)$。
181233
@@ -269,6 +321,81 @@ function integerBreak(n: number): number {
269321}
270322```
271323
324+ #### Rust
325+
326+ ``` rust
327+ impl Solution {
328+ pub fn integer_break (n : i32 ) -> i32 {
329+ if n < 4 {
330+ return n - 1 ;
331+ }
332+ match n % 3 {
333+ 0 => return (3 as i32 ). pow ((n / 3 ) as u32 ),
334+ 1 => return (3 as i32 ). pow ((n / 3 - 1 ) as u32 ) * 4 ,
335+ _ => return (3 as i32 ). pow ((n / 3 ) as u32 ) * 2 ,
336+ }
337+ }
338+ }
339+ ```
340+
341+ #### JavaScript
342+
343+ ``` js
344+ /**
345+ * @param {number} n
346+ * @return {number}
347+ */
348+ var integerBreak = function (n ) {
349+ if (n < 4 ) {
350+ return n - 1 ;
351+ }
352+ const m = Math .floor (n / 3 );
353+ if (n % 3 == 0 ) {
354+ return 3 ** m;
355+ }
356+ if (n % 3 == 1 ) {
357+ return 3 ** (m - 1 ) * 4 ;
358+ }
359+ return 3 ** m * 2 ;
360+ };
361+ ```
362+
363+ #### C#
364+
365+ ``` cs
366+ public class Solution {
367+ public int IntegerBreak (int n ) {
368+ if (n < 4 ) {
369+ return n - 1 ;
370+ }
371+ if (n % 3 == 0 ) {
372+ return (int )Math .Pow (3 , n / 3 );
373+ }
374+ if (n % 3 == 1 ) {
375+ return (int )Math .Pow (3 , n / 3 - 1 ) * 4 ;
376+ }
377+ return (int )Math .Pow (3 , n / 3 ) * 2 ;
378+ }
379+ }
380+ ```
381+
382+ #### C
383+
384+ ``` c
385+ int integerBreak (int n) {
386+ if (n < 4) {
387+ return n - 1;
388+ }
389+ if (n % 3 == 0) {
390+ return (int) pow(3, n / 3);
391+ }
392+ if (n % 3 == 1) {
393+ return (int) pow(3, n / 3 - 1) * 4;
394+ }
395+ return (int) pow(3, n / 3) * 2;
396+ }
397+ ```
398+
272399<!-- tabs:end -->
273400
274401<!-- solution:end -->
0 commit comments