回答編集履歴
6
テキスト修正
test
CHANGED
@@ -402,7 +402,7 @@
|
|
402
402
|
|
403
403
|
|
404
404
|
|
405
|
-
- [https://repl.it/@jun68ykt/Q2
|
405
|
+
- [https://repl.it/@jun68ykt/Q192033](https://repl.it/@jun68ykt/Q192033)
|
406
406
|
|
407
407
|
|
408
408
|
|
5
テキスト修正
test
CHANGED
@@ -337,3 +337,81 @@
|
|
337
337
|
|
338
338
|
|
339
339
|
上記は二重のループがないので、 `O(n)` で済んでいます。
|
340
|
+
|
341
|
+
|
342
|
+
|
343
|
+
### 追記2
|
344
|
+
|
345
|
+
|
346
|
+
|
347
|
+
上記のコードが正解ではないことを、コメントからご指摘、ありがとうございます。
|
348
|
+
|
349
|
+
自分でやろうと思ったのですが、たぶんどこかに良質な回答のコードがあるだろうと思って調べましたところ、以下を見つけました。
|
350
|
+
|
351
|
+
|
352
|
+
|
353
|
+
- Stackoverflow: [Maximum sum sublist? の回答](https://stackoverflow.com/a/15063394)
|
354
|
+
|
355
|
+
|
356
|
+
|
357
|
+
|
358
|
+
|
359
|
+
> If you want the start and end slice indices, too, you need to track a few more bits of information (note this is still O(1) space and O(n) time, it's just a bit hairier):
|
360
|
+
|
361
|
+
|
362
|
+
|
363
|
+
```python
|
364
|
+
|
365
|
+
def mssl(l):
|
366
|
+
|
367
|
+
best = cur = 0
|
368
|
+
|
369
|
+
curi = starti = besti = 0
|
370
|
+
|
371
|
+
for ind, i in enumerate(l):
|
372
|
+
|
373
|
+
if cur+i > 0:
|
374
|
+
|
375
|
+
cur += i
|
376
|
+
|
377
|
+
else: # reset start position
|
378
|
+
|
379
|
+
cur, curi = 0, ind+1
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
if cur > best:
|
384
|
+
|
385
|
+
starti, besti, best = curi, ind+1, cur
|
386
|
+
|
387
|
+
return starti, besti, best
|
388
|
+
|
389
|
+
```
|
390
|
+
|
391
|
+
|
392
|
+
|
393
|
+
上記に対して、
|
394
|
+
|
395
|
+
|
396
|
+
|
397
|
+
`A = [-1, 5, -10, 9, -4, 18, -10, 30, 23, -26, 37, 48, -19, -13, 31]`
|
398
|
+
|
399
|
+
|
400
|
+
|
401
|
+
を与えたサンプルを以下に作成しました。
|
402
|
+
|
403
|
+
|
404
|
+
|
405
|
+
- [https://repl.it/@jun68ykt/Q284975](https://repl.it/@jun68ykt/Q284975)
|
406
|
+
|
407
|
+
|
408
|
+
|
409
|
+
上記を実行すると
|
410
|
+
|
411
|
+
|
412
|
+
|
413
|
+
> (3, 12, 125)
|
414
|
+
|
415
|
+
|
416
|
+
|
417
|
+
と表示されます。このコードの場合、 `(開始, 終端, 合計)` を返しており、`終端` は含まない形式で返してくれます。
|
4
テキスト修正
test
CHANGED
@@ -258,7 +258,7 @@
|
|
258
258
|
|
259
259
|
|
260
260
|
|
261
|
-
|
261
|
+
すべての部分リストを調べなくても、以下で大丈夫かなと思います。
|
262
262
|
|
263
263
|
|
264
264
|
|
@@ -336,4 +336,4 @@
|
|
336
336
|
|
337
337
|
|
338
338
|
|
339
|
-
上記は `O(n)`
|
339
|
+
上記は二重のループがないので、 `O(n)` で済んでいます。
|
3
テキスト修正
test
CHANGED
@@ -249,3 +249,91 @@
|
|
249
249
|
|
250
250
|
|
251
251
|
以上、参考になれば幸いです。
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
### 追記
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
55 個のすべての部分リストを調べなくても、以下で大丈夫かなと思います。
|
262
|
+
|
263
|
+
|
264
|
+
|
265
|
+
```python3
|
266
|
+
|
267
|
+
def solution(A):
|
268
|
+
|
269
|
+
start = None
|
270
|
+
|
271
|
+
end = None
|
272
|
+
|
273
|
+
|
274
|
+
|
275
|
+
if len(A) == 0:
|
276
|
+
|
277
|
+
return 0, start, end
|
278
|
+
|
279
|
+
|
280
|
+
|
281
|
+
# 開始インデクスを求める
|
282
|
+
|
283
|
+
start = 0
|
284
|
+
|
285
|
+
tmp = 0
|
286
|
+
|
287
|
+
for i in range(len(A)):
|
288
|
+
|
289
|
+
tmp += A[i]
|
290
|
+
|
291
|
+
if tmp <= 0 and i+1 < len(A):
|
292
|
+
|
293
|
+
start = i+1
|
294
|
+
|
295
|
+
|
296
|
+
|
297
|
+
# 終端インデクスを求める
|
298
|
+
|
299
|
+
tmp = 0
|
300
|
+
|
301
|
+
max_total = None
|
302
|
+
|
303
|
+
|
304
|
+
|
305
|
+
for j in range(start, len(A)):
|
306
|
+
|
307
|
+
tmp += A[j]
|
308
|
+
|
309
|
+
if max_total is None or tmp > max_total:
|
310
|
+
|
311
|
+
end = j
|
312
|
+
|
313
|
+
max_total = tmp
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
return max_total, start, end
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
if __name__ == '__main__':
|
324
|
+
|
325
|
+
A = [-1, 5, -10, 9, -4, 18, -10, 30, 23, -26, 37, 48, -19, -13, 31]
|
326
|
+
|
327
|
+
ans = solution(A)
|
328
|
+
|
329
|
+
print(ans)
|
330
|
+
|
331
|
+
```
|
332
|
+
|
333
|
+
|
334
|
+
|
335
|
+
> (120, 5, 11)
|
336
|
+
|
337
|
+
|
338
|
+
|
339
|
+
上記は `O(n)` になっているかと思います。
|
2
テキスト修正
test
CHANGED
@@ -40,7 +40,7 @@
|
|
40
40
|
|
41
41
|
|
42
42
|
|
43
|
-
ご質問に上げられているコードでは何が拙いかというと、合計の比較の際に、以下のようにしている箇所です。
|
43
|
+
まず、ご質問に上げられているコードでは何が拙いかというと、合計の比較の際に、以下のようにしている箇所です。
|
44
44
|
|
45
45
|
|
46
46
|
|
@@ -82,17 +82,13 @@
|
|
82
82
|
|
83
83
|
|
84
84
|
|
85
|
-
あるはずです。
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
あるはずです。これを抑えたうえで、二重のループによって、合計を算出すべき部分リストが 55 種類出現しているかという観点で、見直されるとよいかと思います。
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
95
|
-
具体的な修正ですが、ご質問にあるコードをなるべく活かすとすると、たとえば以下のようになるかと思います。
|
91
|
+
次に、具体的な修正案ですが、ご質問にあるコードをなるべく活かすとすると、たとえば以下のようになるかと思います。
|
96
92
|
|
97
93
|
|
98
94
|
|
@@ -172,9 +168,7 @@
|
|
172
168
|
|
173
169
|
|
174
170
|
|
175
|
-
もうひとつ別解を以下に
|
171
|
+
もうひとつ別解を以下に挙げます。
|
176
|
-
|
177
|
-
|
178
172
|
|
179
173
|
```python3
|
180
174
|
|
@@ -224,7 +218,23 @@
|
|
224
218
|
|
225
219
|
|
226
220
|
|
227
|
-
上記で、 `sorted` の第1引数になる、内包表記によるリスト
|
221
|
+
上記で、 `sorted` の第1引数になる、内包表記によるリスト
|
222
|
+
|
223
|
+
```pyhon3
|
224
|
+
|
225
|
+
[(sum(A[i:j+1]), i, j)
|
226
|
+
|
227
|
+
for i in range(len(A))
|
228
|
+
|
229
|
+
for j in range(len(A))
|
230
|
+
|
231
|
+
if i <= j
|
232
|
+
|
233
|
+
]
|
234
|
+
|
235
|
+
```
|
236
|
+
|
237
|
+
は、以下のようなタプル
|
228
238
|
|
229
239
|
|
230
240
|
|
1
テキスト修正
test
CHANGED
@@ -30,11 +30,11 @@
|
|
30
30
|
|
31
31
|
|
32
32
|
|
33
|
-
`(合計値の最大値, 合計が最大になる部分
|
33
|
+
`(合計値の最大値, 合計が最大になる部分リストの開始インデクス, 合計が最大になる部分配列の終端インデクス)`
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
-
という要素が3つのタプルで、`合計が最大になる部分
|
37
|
+
という要素が3つのタプルで、`合計が最大になる部分リストの終端インデクス` も、合計の対象に**含まれる** と解釈しました。以下、これを前提とした回答になります。
|
38
38
|
|
39
39
|
|
40
40
|
|
@@ -74,7 +74,7 @@
|
|
74
74
|
|
75
75
|
|
76
76
|
|
77
|
-
開始インデクスを `i` ( 0<=i<len(A) )とすると 終端インデクスの取り得る場合の数は `len(A)-i` 個 で 、いま `len(A) は` 10 なので、比較対象となる合計値は、**重複を考慮しなければ(すなわち、異なる部分
|
77
|
+
開始インデクスを `i` ( 0<=i<len(A) )とすると 終端インデクスの取り得る場合の数は `len(A)-i` 個 で 、いま `len(A) は` 10 なので、比較対象となる合計値は、**重複を考慮しなければ(すなわち、異なる部分リストの要素の合計が(たまたま)一致してもそれらは個別に数えるとして、)**
|
78
78
|
|
79
79
|
|
80
80
|
|
@@ -154,7 +154,7 @@
|
|
154
154
|
|
155
155
|
|
156
156
|
|
157
|
-
と表示されます。開始インデクス `0` 、終端インデクス `6`(※これも含む) であるAの部分
|
157
|
+
と表示されます。開始インデクス `0` 、終端インデクス `6`(※これも含む) であるAの部分リスト
|
158
158
|
|
159
159
|
```
|
160
160
|
|
@@ -228,11 +228,11 @@
|
|
228
228
|
|
229
229
|
|
230
230
|
|
231
|
-
`(部分
|
231
|
+
`(部分リストの要素の合計値, 部分リストの開始インデクス, 部分リストの終端インデクス)`
|
232
|
-
|
233
|
-
|
234
|
-
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
-
を、`A` の部分
|
235
|
+
を、`A` の部分リストのすべてについて含み、このリストの長さは先に求めた、場合の数の **55** になります。
|
236
236
|
|
237
237
|
|
238
238
|
|