ツーポインタで水を最も多くためる 2 本の板を選ぶ

高さの​違う​板の​並びから​ 2 本を​選び、​間に​ためられる​水の​量の​いちばん​大きい値を​返します。​両端に​指を​置き、​低い側の​指だけを​内側へ​寄せる​理由まで​言える​練習です。

海外で定番の問題リスト 4 本のうち 4 本に入っています (Blind 75、NeetCode 150、Grind 75、LeetCode Top Interview 150)

問題

等しい間隔で立てた板の高さの並び heights を受け取ります。i 番目の板は位置 i に立っています。2 本の板を選ぶと、その間に水をためられます。ためられる水の量は「2 本のうち低い方の高さ」と「2 本の位置の差」を掛けた物です。ためられる水の量のいちばん大きい値を返す関数を書いてください。

  • 間にある板は水をさえぎりません。選んだ 2 本だけで量が決まります
  • heights の長さは 2 以上 100000 以下、高さはどれも 0 以上 10000 以下です

入力と出力の例

例 1

両端の板を選ぶと、低い方の 3 と位置の差 4 で 12 になります。

入力

heights = [3, 1, 4, 2, 5]

出力

12

例 2

いちばん高い板どうしが、いちばん多くためるとは限りません。

入力

heights = [2, 9, 1, 1, 8, 3]

出力

24

例 3

板が 2 本だけでも、位置の差は 1 です。

入力

heights = [6, 6]

出力

6

面接での聞かれ方

面接では、絵を描いて見せながら聞かれることが多い問題です。

  • 「棒の高さの配列があります。2 本選んで、いちばん多く水をためられる量を返してください」
  • 2 重の繰り返しを見せると、「O(n) にできますか?」と続きます
  • ツーポインタで書くと、必ず「なぜ低い方を動かしてよいのですか? 答えを飛ばしませんか?」と聞かれます

書けることより、指を動かしてよい理由を言葉で言えるかが見られています。

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

main.py
def max_water(heights):
    # ここに書きます
    pass


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

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