スライディングウィンドウで幅 k の平均が最大の所を探す

整数の​並びで、​続いた​ k 個の​平均が​いちばん​大きくなる​所を​探し、​その​ k 個の​合計を​返します。​窓を​ 1 つずらすたびに、​入る​数を​足して​出る​数を​引く​練習です。

海外で定番の問題リスト 4 本には入っていません

問題

ある店の毎日の売り上げの増減を並べた整数の並び nums と、日数 k を受け取ります。続いた k 日の平均がいちばん大きくなる所を探し、その k 日の合計を返す関数を書いてください。

  • 幅はいつも k で同じなので、平均がいちばん大きい所は、合計がいちばん大きい所と同じです。小数の誤差を持ち込まないように、平均ではなく合計を返します (平均が欲しければ、返した合計を k で割れば求まります)
  • k は 1 以上、nums の長さ以下です
  • nums の長さは 1 以上 100000 以下、値はどれも -10000 以上 10000 以下です

入力と出力の例

例 1

続いた 3 日の合計は、前から 9、7、5、4 です。いちばん大きい 9 を返します。

入力

nums = [4, -1, 6, 2, -3, 5]
k = 3

出力

9

例 2

全部が負の数のときも、いちばん大きい合計 (0 に近い方) を返します。

入力

nums = [-5, -2, -8, -1]
k = 2

出力

-7

例 3

k が並びの長さと同じなら、窓は 1 つだけです。

入力

nums = [3, 1, 2]
k = 3

出力

6

面接での聞かれ方

面接では、短く次のように渡されることが多いです。

  • 「整数の配列と k があります。長さ k の連続した部分で、平均の最大を求めてください」
  • 平均を返す形で聞かれたら、「合計の最大を求めてから最後に 1 回だけ k で割ります」と答えると、割り算を窓ごとにしないで済みます
  • 書き終えたあとに「長さが k 以上なら何でもよいとしたら?」と続きを聞かれることがあります。これは二分探索を組み合わせるシニアの問題になるので、ジュニアでは考え方の向きが言えれば十分です

ジュニアの問題なので、窓をずらすときに全部を足し直さないことと、最初の窓の作り方が見られます。

アルゴリズムのチートシートの「配列と文字列」に、​この​型の​要点を​表と​コードで​まとめています。

main.py
def max_window_sum(nums, k):
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(max_window_sum([4, -1, 6, 2, -3, 5], 3))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します