31
31
<pre >
32
32
<strong >输入:</strong > nums = [9,1,2,3,9], k = 3
33
33
<strong >输出:</strong > 20.00000
34
- <strong >解释:</strong >
35
- nums 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) / 3 + 9 = 20.
36
- 我们也可以把 nums 分成[9, 1], [2], [3, 9].
34
+ <strong >解释:</strong >
35
+ nums 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) / 3 + 9 = 20.
36
+ 我们也可以把 nums 分成[9, 1], [2], [3, 9].
37
37
这样的分组得到的分数为 5 + 2 + 6 = 13, 但不是最大值.
38
38
</pre >
39
39
@@ -64,17 +64,17 @@ nums 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) /
64
64
65
65
我们可以先预处理得到前缀和数组 $s$,方便快速得到子数组的和。
66
66
67
- 然后设计一个函数 $ dfs(i, k)$,表示从数组下标 $i$ 开始,最多分成 $k$ 组的最大平均值和。答案为 $dfs(0, k)$。函数 $dfs(i, k)$ 的执行逻辑如下:
67
+ 接下来,我们设计一个函数 $\textit{ dfs} (i, k)$,表示从数组下标 $i$ 开始,最多分成 $k$ 组的最大平均值和。答案为 $\textit{ dfs} (0, k)$。
68
68
69
- 当 $i=n$ 时,表示已经遍历到数组末尾,此时返回 $0$。
69
+ 函数 $\textit{dfs}(i, k)$ 的执行逻辑如下:
70
70
71
- 当 $k=1 $ 时,表示只剩下一组,此时返回从下标 $i$ 开始到数组末尾的平均值 。
71
+ 当 $i = n $ 时,表示已经遍历到数组末尾,此时返回 $0$ 。
72
72
73
- 否则,我们在 $ [ i, ..n-1 ] $ 的范围内枚举分组的结束位置 $j$,计算从下标 $i$ 到下标 $j$ 的平均值,以及从下标 $j+1$ 开始,最多分成 $k-1$ 组的最大平均值和。取其中的最大值作为答案 。
73
+ 当 $k = 1$ 时,表示只剩下一组,此时返回从下标 $i$ 开始到数组末尾的平均值 。
74
74
75
- 为了避免重复计算,我们可以用数组 $f$ 记忆化函数 $ dfs(i , k)$ 的返回值 。
75
+ 否则,我们在 $ [ i + 1, n)$ 的区间内枚举下一个分组的开始位置 $j$,计算从 $i$ 到 $j - 1$ 的平均值 $\frac{s [ j ] - s [ i ] }{j - i}$,加上 $\textit{ dfs}(j , k - 1 )$ 的结果,取所有结果的最大值 。
76
76
77
- 时间复杂度 $O(n^2 \times k)$,空间复杂度 $O(n \times k)$。其中 $n$ 表示数组 ` nums ` 的长度。
77
+ 时间复杂度 $O(n^2 \times k)$,空间复杂度 $O(n \times k)$。其中 $n$ 表示数组 $\textit{ nums}$ 的长度。
78
78
79
79
<!-- tabs:start -->
80
80
@@ -84,15 +84,14 @@ nums 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) /
84
84
class Solution :
85
85
def largestSumOfAverages (self , nums : List[int ], k : int ) -> float :
86
86
@cache
87
- def dfs (i , k ) :
87
+ def dfs (i : int , k : int ) -> float :
88
88
if i == n:
89
89
return 0
90
90
if k == 1 :
91
- return (s[- 1 ] - s[i]) / (n - i)
91
+ return (s[n ] - s[i]) / (n - i)
92
92
ans = 0
93
- for j in range (i, n):
94
- t = (s[j + 1 ] - s[i]) / (j - i + 1 ) + dfs(j + 1 , k - 1 )
95
- ans = max (ans, t)
93
+ for j in range (i + 1 , n):
94
+ ans = max (ans, (s[j] - s[i]) / (j - i) + dfs(j, k - 1 ))
96
95
return ans
97
96
98
97
n = len (nums)
@@ -111,7 +110,7 @@ class Solution {
111
110
public double largestSumOfAverages (int [] nums , int k ) {
112
111
n = nums. length;
113
112
s = new int [n + 1 ];
114
- f = new Double [n + 1 ][k + 1 ];
113
+ f = new Double [n][k + 1 ];
115
114
for (int i = 0 ; i < n; ++ i) {
116
115
s[i + 1 ] = s[i] + nums[i];
117
116
}
@@ -129,9 +128,8 @@ class Solution {
129
128
return f[i][k];
130
129
}
131
130
double ans = 0 ;
132
- for (int j = i; j < n; ++ j) {
133
- double t = (s[j + 1 ] - s[i]) * 1.0 / (j - i + 1 ) + dfs(j + 1 , k - 1 );
134
- ans = Math . max(ans, t);
131
+ for (int j = i + 1 ; j < n; ++ j) {
132
+ ans = Math . max(ans, (s[j] - s[i]) * 1.0 / (j - i) + dfs(j, k - 1 ));
135
133
}
136
134
return f[i][k] = ans;
137
135
}
@@ -147,21 +145,28 @@ public:
147
145
int n = nums.size();
148
146
int s[ n + 1] ;
149
147
double f[ n] [ k + 1 ] ;
148
+ memset(f, 0, sizeof(f));
150
149
s[ 0] = 0;
151
- memset(f, 0, sizeof f);
152
- for (int i = 0; i < n; ++i) s[ i + 1] = s[ i] + nums[ i] ;
153
- function<double(int, int)> dfs = [ &] (int i, int k) -> double {
154
- if (i == n) return 0;
155
- if (k == 1) return (s[ n] - s[ i] ) * 1.0 / (n - i);
156
- if (f[ i] [ k ] ) return f[ i] [ k ] ;
150
+ for (int i = 0; i < n; ++i) {
151
+ s[ i + 1] = s[ i] + nums[ i] ;
152
+ }
153
+ auto dfs = [ &] (auto&& dfs, int i, int k) -> double {
154
+ if (i == n) {
155
+ return 0;
156
+ }
157
+ if (k == 1) {
158
+ return (s[ n] - s[ i] ) * 1.0 / (n - i);
159
+ }
160
+ if (f[ i] [ k ] > 0) {
161
+ return f[ i] [ k ] ;
162
+ }
157
163
double ans = 0;
158
- for (int j = i; j < n; ++j) {
159
- double t = (s[ j + 1] - s[ i] ) * 1.0 / (j - i + 1) + dfs(j + 1, k - 1);
160
- ans = max(ans, t);
164
+ for (int j = i + 1; j < n; ++j) {
165
+ ans = max(ans, (s[ j] - s[ i] ) * 1.0 / (j - i) + dfs(dfs, j, k - 1));
161
166
}
162
167
return f[ i] [ k ] = ans;
163
168
};
164
- return dfs(0, k);
169
+ return dfs(dfs, 0, k);
165
170
}
166
171
};
167
172
```
@@ -172,25 +177,27 @@ public:
172
177
func largestSumOfAverages(nums []int, k int) float64 {
173
178
n := len(nums)
174
179
s := make([]int, n+1)
175
- f := [110][110]float64{}
176
- for i, v := range nums {
177
- s[i+1] = s[i] + v
180
+ for i, x := range nums {
181
+ s[i+1] = s[i] + x
178
182
}
179
- var dfs func(i, k int) float64
183
+ f := make([][]float64, n)
184
+ for i := range f {
185
+ f[i] = make([]float64, k+1)
186
+ }
187
+ var dfs func(int, int) float64
180
188
dfs = func(i, k int) float64 {
181
189
if i == n {
182
190
return 0
183
191
}
184
- if k == 1 {
185
- return float64(s[n]-s[i]) / float64(n-i)
186
- }
187
192
if f[i][k] > 0 {
188
193
return f[i][k]
189
194
}
190
- var ans float64
191
- for j := i; j < n; j++ {
192
- t := float64(s[j+1]-s[i])/float64(j-i+1) + dfs(j+1, k-1)
193
- ans = math.Max(ans, t)
195
+ if k == 1 {
196
+ return float64(s[n]-s[i]) / float64(n-i)
197
+ }
198
+ ans := 0.0
199
+ for j := i + 1; j < n; j++ {
200
+ ans = math.Max(ans, float64(s[j]-s[i])/float64(j-i)+dfs(j, k-1))
194
201
}
195
202
f[i][k] = ans
196
203
return ans
@@ -199,6 +206,167 @@ func largestSumOfAverages(nums []int, k int) float64 {
199
206
}
200
207
```
201
208
209
+ #### TypeScript
210
+
211
+ ``` ts
212
+ function largestSumOfAverages(nums : number [], k : number ): number {
213
+ const n = nums .length ;
214
+ const s: number [] = Array (n + 1 ).fill (0 );
215
+ for (let i = 0 ; i < n ; i ++ ) {
216
+ s [i + 1 ] = s [i ] + nums [i ];
217
+ }
218
+ const f: number [][] = Array .from ({ length: n }, () => Array (k + 1 ).fill (0 ));
219
+ const dfs = (i : number , k : number ): number => {
220
+ if (i === n ) {
221
+ return 0 ;
222
+ }
223
+ if (f [i ][k ] > 0 ) {
224
+ return f [i ][k ];
225
+ }
226
+ if (k === 1 ) {
227
+ return (s [n ] - s [i ]) / (n - i );
228
+ }
229
+ for (let j = i + 1 ; j < n ; j ++ ) {
230
+ f [i ][k ] = Math .max (f [i ][k ], dfs (j , k - 1 ) + (s [j ] - s [i ]) / (j - i ));
231
+ }
232
+ return f [i ][k ];
233
+ };
234
+ return dfs (0 , k );
235
+ }
236
+ ```
237
+
238
+ <!-- tabs: end -->
239
+
240
+ <!-- solution: end -->
241
+
242
+ <!-- solution: start -->
243
+
244
+ ### 方法二:动态规划
245
+
246
+ 我们可以将方法一的记忆化搜索转化为动态规划。
247
+
248
+ 定义 $f[ i] [ j ] $ 表示数组 $\textit{nums}$ 的前 $i$ 个元素最多分成 $j$ 组的最大平均值和。答案为 $f[ n] [ k ] $。
249
+
250
+ 对于 $f[ i] [ j ] $,我们可以枚举上一组的结束位置 $h$,计算 $f[ h] [ j-1 ] $,加上 $\frac{s[ i] -s[ h] }{i-h}$ 的结果,取所有结果的最大值。
251
+
252
+ 时间复杂度 $O(n^2 \times k)$,空间复杂度 $O(n \times k)$。其中 $n$ 表示数组 $\textit{nums}$ 的长度。
253
+
254
+ <!-- tabs: start -->
255
+
256
+ #### Python3
257
+
258
+ ``` python
259
+ class Solution :
260
+ def largestSumOfAverages (self , nums : List[int ], k : int ) -> float :
261
+ n = len (nums)
262
+ f = [[0 ] * (k + 1 ) for _ in range (n + 1 )]
263
+ s = list (accumulate(nums, initial = 0 ))
264
+ for i in range (1 , n + 1 ):
265
+ f[i][1 ] = s[i] / i
266
+ for j in range (2 , min (i + 1 , k + 1 )):
267
+ for h in range (i):
268
+ f[i][j] = max (f[i][j], f[h][j - 1 ] + (s[i] - s[h]) / (i - h))
269
+ return f[n][k]
270
+ ```
271
+
272
+ #### Java
273
+
274
+ ``` java
275
+ class Solution {
276
+ public double largestSumOfAverages (int [] nums , int k ) {
277
+ int n = nums. length;
278
+ double [][] f = new double [n + 1 ][k + 1 ];
279
+ int [] s = new int [n + 1 ];
280
+ for (int i = 0 ; i < n; ++ i) {
281
+ s[i + 1 ] = s[i] + nums[i];
282
+ }
283
+ for (int i = 1 ; i <= n; ++ i) {
284
+ f[i][1 ] = s[i] * 1.0 / i;
285
+ for (int j = 2 ; j <= Math . min(i, k); ++ j) {
286
+ for (int h = 0 ; h < i; ++ h) {
287
+ f[i][j] = Math . max(f[i][j], f[h][j - 1 ] + (s[i] - s[h]) * 1.0 / (i - h));
288
+ }
289
+ }
290
+ }
291
+ return f[n][k];
292
+ }
293
+ }
294
+ ```
295
+
296
+ #### C++
297
+
298
+ ``` cpp
299
+ class Solution {
300
+ public:
301
+ double largestSumOfAverages(vector<int >& nums, int k) {
302
+ int n = nums.size();
303
+ int s[ n + 1] ;
304
+ s[ 0] = 0;
305
+ double f[ n + 1] [ k + 1 ] ;
306
+ memset(f, 0, sizeof(f));
307
+ for (int i = 0; i < n; ++i) {
308
+ s[ i + 1] = s[ i] + nums[ i] ;
309
+ }
310
+ for (int i = 1; i <= n; ++i) {
311
+ f[ i] [ 1 ] = s[ i] * 1.0 / i;
312
+ for (int j = 2; j <= min(i, k); ++j) {
313
+ for (int h = 0; h < i; ++h) {
314
+ f[ i] [ j ] = max(f[ i] [ j ] , f[ h] [ j - 1 ] + (s[ i] - s[ h] ) * 1.0 / (i - h));
315
+ }
316
+ }
317
+ }
318
+ return f[ n] [ k ] ;
319
+ }
320
+ };
321
+ ```
322
+
323
+ #### Go
324
+
325
+ ```go
326
+ func largestSumOfAverages(nums []int, k int) float64 {
327
+ n := len(nums)
328
+ s := make([]int, n+1)
329
+ for i, x := range nums {
330
+ s[i+1] = s[i] + x
331
+ }
332
+ f := make([][]float64, n+1)
333
+ for i := range f {
334
+ f[i] = make([]float64, k+1)
335
+ }
336
+ for i := 1; i <= n; i++ {
337
+ f[i][1] = float64(s[i]) / float64(i)
338
+ for j := 2; j <= min(i, k); j++ {
339
+ for h := 0; h < i; h++ {
340
+ f[i][j] = max(f[i][j], f[h][j-1]+float64(s[i]-s[h])/float64(i-h))
341
+ }
342
+ }
343
+ }
344
+ return f[n][k]
345
+ }
346
+ ```
347
+
348
+ #### TypeScript
349
+
350
+ ``` ts
351
+ function largestSumOfAverages(nums : number [], k : number ): number {
352
+ const n = nums .length ;
353
+ const s: number [] = Array (n + 1 ).fill (0 );
354
+ for (let i = 0 ; i < n ; i ++ ) {
355
+ s [i + 1 ] = s [i ] + nums [i ];
356
+ }
357
+ const f: number [][] = Array .from ({ length: n + 1 }, () => Array (k + 1 ).fill (0 ));
358
+ for (let i = 1 ; i <= n ; ++ i ) {
359
+ f [i ][1 ] = s [i ] / i ;
360
+ for (let j = 2 ; j <= Math .min (i , k ); ++ j ) {
361
+ for (let h = 0 ; h < i ; ++ h ) {
362
+ f [i ][j ] = Math .max (f [i ][j ], f [h ][j - 1 ] + (s [i ] - s [h ]) / (i - h ));
363
+ }
364
+ }
365
+ }
366
+ return f [n ][k ];
367
+ }
368
+ ```
369
+
202
370
<!-- tabs: end -->
203
371
204
372
<!-- solution: end -->
0 commit comments