From b7c9eede239e072dbe60e0986acd0b16e7b92264 Mon Sep 17 00:00:00 2001 From: tom4649 Date: Sun, 29 Mar 2026 18:13:32 +0900 Subject: [PATCH 1/2] 122. Best Time to Buy and Sell Stock II --- 122/memo.md | 30 ++++++++++++++++++++++++++++++ 122/sol1.py | 10 ++++++++++ 122/sol2.py | 20 ++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 122/memo.md create mode 100644 122/sol1.py create mode 100644 122/sol2.py diff --git a/122/memo.md b/122/memo.md new file mode 100644 index 0000000..bfec27c --- /dev/null +++ b/122/memo.md @@ -0,0 +1,30 @@ +# 122. Best Time to Buy and Sell Stock II + +- 答えを見てしまった: sol1.py + - 悔しい + +https://github.com/tshimosake/arai60/pull/22/changes#diff-e262fd39a7deae3a1286c7400da3b1317672ae42e34582d8218de2c31f244292 + +> 最適解を $\sum_{k=1}^{n-1} \max(0, p_k - p_{k-1})$ と分解できることが本質だった。 + +つまり、i日に買ってj日に得る利益は $\sum_{k=i+1}^{j} (p_k - p_{k-1})$と分解できるので、これを最大化すると上の最適解となる + +https://github.com/goto-untrapped/Arai60/pull/59#discussion_r1782748689 + +> 毎日できることは、株を持っているか、お金を持っているかの2択なので、未来が見える人になったとして、どちらがいいかを考えればいいのです。 + +https://github.com/tshimosake/arai60/pull/22/changes#diff-e262fd39a7deae3a1286c7400da3b1317672ae42e34582d8218de2c31f244292 + +> 二状態DP:各日で株を持っている/持っていない場合の最大利益を更新していって、最後に持っていない場合の最大利益を返す。関数呼び出しが頻繁にあるからか、少し遅くなった + +なるほど。今株を持っているか持っていないかの二つを更新し続ければ良いのか。自分で答えに辿り着きたかった。 + +- sol2.py + +https://github.com/mamo3gr/arai60/blob/122_best-time-to-buy--and-sell-stock-ii/122_best-time-to-buy--and-sell-stock-ii/memo.md + +> max を使うほうがコードはシンプルなんだけど、前日からの差分で利益が出ているか見る、利益があるなら累積する、と手続きを書き下すほうがちょっとだけ分かりやすいような気がする。 + +なるほど。可読性ではこちらの方が高そう。 + +解けずに答えを再現しただけになったので、もう一回解きたい。 diff --git a/122/sol1.py b/122/sol1.py new file mode 100644 index 0000000..878aa3e --- /dev/null +++ b/122/sol1.py @@ -0,0 +1,10 @@ +class Solution: + def maxProfit(self, prices: List[int]) -> int: + if len(prices) < 1: + return 0 + + max_profit = 0 + for i in range(len(prices) - 1): + max_profit += max(0, prices[i + 1] - prices[i]) + + return max_profit diff --git a/122/sol2.py b/122/sol2.py new file mode 100644 index 0000000..cc9ba25 --- /dev/null +++ b/122/sol2.py @@ -0,0 +1,20 @@ +class Solution: + def maxProfit(self, prices: List[int]) -> int: + if not prices: + raise ValueError("The input list is empty") + + profit_holding_stock = -prices[0] + profit_not_holding_stock = 0 + for price in prices[1:]: + next_profit_holding_stock = max( + profit_holding_stock, profit_not_holding_stock - price + ) + next_profit_not_holding_stock = max( + profit_not_holding_stock, profit_holding_stock + price + ) + profit_holding_stock, profit_not_holding_stock = ( + next_profit_holding_stock, + next_profit_not_holding_stock, + ) + + return profit_not_holding_stock From d348af5fb4de7e6d13e11bd85216b09499170211 Mon Sep 17 00:00:00 2001 From: tom4649 Date: Mon, 30 Mar 2026 06:58:21 +0900 Subject: [PATCH 2/2] Add suggested changes --- 122/sol1.py | 2 +- 122/sol2.py | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/122/sol1.py b/122/sol1.py index 878aa3e..db75614 100644 --- a/122/sol1.py +++ b/122/sol1.py @@ -1,6 +1,6 @@ class Solution: def maxProfit(self, prices: List[int]) -> int: - if len(prices) < 1: + if not prices: return 0 max_profit = 0 diff --git a/122/sol2.py b/122/sol2.py index cc9ba25..3a095af 100644 --- a/122/sol2.py +++ b/122/sol2.py @@ -1,7 +1,7 @@ class Solution: def maxProfit(self, prices: List[int]) -> int: if not prices: - raise ValueError("The input list is empty") + return 0 profit_holding_stock = -prices[0] profit_not_holding_stock = 0 @@ -12,9 +12,7 @@ def maxProfit(self, prices: List[int]) -> int: next_profit_not_holding_stock = max( profit_not_holding_stock, profit_holding_stock + price ) - profit_holding_stock, profit_not_holding_stock = ( - next_profit_holding_stock, - next_profit_not_holding_stock, - ) + profit_holding_stock = next_profit_holding_stock + profit_not_holding_stock = next_profit_not_holding_stock return profit_not_holding_stock