窓の左端に最安値を置いて 1 回の売り買いの利益を最大にする

日ごとの​値段の​並びから、​1 回だけ​買って、​それより​後の​日に​ 1 回だけ売る​ときの、​いちばん​大きい利益を​返します。​窓の​左端を​それまでの​最安の​日に​置き、​右端を​ 1 日ず​つ進める​練習です。

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

問題

ある品物の、日ごとの値段の並び prices を受け取ります。並びの順が日の順です。どこか 1 日に 1 つ買い、それより後のどこか 1 日に売ります。売った値段から買った値段を引いた利益のうち、いちばん大きい値を返す関数を書いてください。

  • 買う日は売る日より前でなければなりません。同じ日に買って売ることはできません
  • どう売り買いしても利益が出ないときは、売り買いをしないことにして 0 を返します
  • prices の長さは 1 以上 100000 以下、値段はどれも 0 以上 10000 以下です

入力と出力の例

例 1

値段 2 の日に買い、その次の値段 7 の日に売ると、5 の利益です。

入力

prices = [8, 3, 6, 2, 7, 4]

出力

5

例 2

値段が下がり続けるなら、売り買いしないのがいちばんです。

入力

prices = [9, 7, 4, 1]

出力

0

例 3

いちばん安い日がいちばん高い日より後にあると、その 2 日では売り買いできません。

入力

prices = [2, 10, 1, 5]

出力

8

面接での聞かれ方

面接では、株の値動きの場面として短く聞かれることが多いです。

  • 「株価の配列があります。1 回だけ買って売るとき、最大の利益はいくらですか?」
  • 「最安値で買って最高値で売ればよいのでは?」と、わざと落とし穴へ誘う形で聞かれることもあります
  • 書き終えたあとに「何回でも売り買いできたらどうしますか?」と、条件を変えた続きが出ることがあります

最初に、買うのは売るより前であること、利益が出ないときに何を返すかを確かめてから書き始めます。

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

main.py
def max_profit(prices):
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(max_profit([8, 3, 6, 2, 7, 4]))

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