Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 43c1acb

Browse files
feat: add solutions to lc problem: No.0343 (doocs#3291)
No.0343.Integer Break
1 parent ec22bab commit 43c1acb

File tree

16 files changed

+454
-89
lines changed

16 files changed

+454
-89
lines changed

‎lcof/面试题14- I. 剪绳子/README.md‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,22 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9
4242

4343
### 方法一:动态规划
4444

45-
我们定义 $f[i]$ 表示正整数 $n$ 能获得的最大乘积,初始化 $f[1] = 1$。答案即为 $f[n]$。
45+
我们定义 $f[i]$ 表示正整数 $i$ 拆分后能获得的最大乘积,初始时 $f[1] = 1$。答案即为 $f[n]$。
4646

47-
状态转移方程为:
47+
考虑 $i$ 最后拆分出的数字 $j,ドル其中 $j \in [1, i)$。对于 $i$ 拆分出的数字 $j,ドル有两种情况:
48+
49+
1. 将 $i$ 拆分成 $i - j$ 和 $j$ 的和,不继续拆分,此时乘积为 $(i - j) \times j$;
50+
2. 将 $i$ 拆分成 $i - j$ 和 $j$ 的和,继续拆分,此时乘积为 $f[i - j] \times j$。
51+
52+
因此,我们可以得到状态转移方程:
4853

4954
$$
5055
f[i] = \max(f[i], f[i - j] \times j, (i - j) \times j) \quad (j \in [0, i))
5156
$$
5257

53-
时间复杂度 $O(n^2),ドル空间复杂度 $O(n)$。其中 $n$ 为正整数 $n$。
58+
最后返回 $f[n]$ 即可。
59+
60+
时间复杂度 $O(n^2),ドル空间复杂度 $O(n)$。其中 $n$ 为给定的正整数。
5461

5562
<!-- tabs:start -->
5663

@@ -208,7 +215,7 @@ class Solution {
208215

209216
### 方法二:数学
210217

211-
当 $n \lt 4$,此时 $n$ 不能拆分成至少两个正整数的和,因此 $n - 1$ 是最大乘积。当 $n \ge 4$ 时,我们尽可能多地拆分 3ドル,ドル当剩下的最后一段为 4ドル$ 时,我们将其拆分为 2ドル + 2,ドル这样乘积最大。
218+
当 $n \lt 4$ 时,由于题目要求至少剪一次,因此 $n - 1$ 是最大乘积。当 $n \ge 4$ 时,我们尽可能多地拆分 3ドル,ドル当剩下的最后一段为 4ドル$ 时,我们将其拆分为 2ドル + 2,ドル这样乘积最大。
212219

213220
时间复杂度 $O(1),ドル空间复杂度 $O(1)$。
214221

‎solution/0300-0399/0343.Integer Break/README.md‎

Lines changed: 158 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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

@@ -70,26 +77,26 @@ $$
7077
```python
7178
class 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
8390
class 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 {
100107
class Solution {
101108
public:
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
118125
func 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
133140
function 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
147154
impl 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+
161209
int 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

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /