Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 121_best_time_to_buy_and_sell_stock/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## 問題: [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/)
26 changes: 26 additions & 0 deletions 121_best_time_to_buy_and_sell_stock/step1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Step 1

- 変数を以下の通りにする
- stockを買う日: `buy_day`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

個人的には最安値で買うという意味を持たせたいなと思いました。
pricesのなかのminを保持したいという意図が伝わりやすい気がしています。

- その日の値段: `price[buy_day]`
- 最大利益: `max_profit`
- forループを回していく中で、`price[i]`が`price[buy_day]`より安い場合は`price[buy_day]`を`price[i]`に更新する。高い場合は`max_profit`を更新する

```python
class Solution:
def maxProfit(self, prices: List[int]) -> int:
max_profit = 0
buy_day = 0

for i, price in enumerate(prices):
if price < prices[buy_day]:
buy_day = i
Copy link
Copy Markdown

@arahi10 arahi10 Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このままでもほとんど問題ないと思いますが ,あえて挙げるなら買う"日" buy_day に"インデックス" i を代入するのがちょっとだけ気になりました.
buy_index などにすると買う日"のインデックス" になって両者が揃うと思います.

(追記)
今後 datetime.date 型の変数を使い始めそうなクラスのメソッドなら個人的に気になるんですが,今回の例なら気にしなくても良いと思います.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

私も...dayという変数にインデックスを入れているのは少し分かりづらい気がしました。
インデックスかビジネスロジックで必要な値かがわかるようにしたいです。
そういう意味で最初のbuy_day=0はループが始まる前に初期化しているので、値の初期値なのかインデックスの始まりなのかがこの時点ではわからないところに少し負荷があるように感じます。
インデックスであることが分かる名前であればこの後ループが出てくることが想像できて読みやすいです。

else:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

step2,3でminを使った実装に置き換えられていて良いと思いました。
if-elseだと分岐をifの分岐条件を頭に入れたままelseが排他的条件の前提で読む必要があって少し認知不可が高い気がしています。
また、レビューでは境界値を考えたときに等価の場合はelse側に寄せるでよいのかなど余計なことを考える必要が出てくる気がするので、minのほうが不要な分岐を見せないことでレビュー観点もシンプルになる気がします。

max_profit = max(max_profit, price - prices[buy_day])

return max_profit
```

時間計算量: O(n)

空間計算量: O(1)
20 changes: 20 additions & 0 deletions 121_best_time_to_buy_and_sell_stock/step2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Step 2

- ループ中にインデックスを気にせずとも書けた

```python
class Solution:
def maxProfit(self, prices: List[int]) -> int:
max_profit = 0
buying_price = prices[0]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

問題の制約上そのような入力は Leet Code からは与えられませんが,開発現場でこのメソッドを実装するなら, prices として空のlistが入力されてもエラーが出ないように実装したいなと思いました.

def maxProfit(self, prices: List[int]) -> int:
    if not prices:
        return 0
    max_profit = 0
    buying_price = prices[0]
    # (以下同じ)


for price in prices:
buying_price = min(buying_price, price)
max_profit = max(max_profit, price - buying_price)

return max_profit
```

時間計算量: O(n)

空間計算量: O(1)
20 changes: 20 additions & 0 deletions 121_best_time_to_buy_and_sell_stock/step3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Step 3

```python
class Solution:
def maxProfit(self, prices: List[int]) -> int:
max_profit = 0
buying_price = prices[0]

for price in prices:
buying_price = min(buying_price, price)
max_profit = max(max_profit, price - buying_price)
Comment on lines +10 to +11
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

個人的には、max_profit の計算を先にしたいと思いました。
元のコードの場合、buying_price が更新されると、その日の内に買って売るという動作が起きているからです(プログラムの全体としては問題なく動いています)


return max_profit
```

1回目: 1分 9秒

2回目: 1分 10秒

3回目: 1分 11秒