From 6e45bca1c1733624fc863309bacb7ea010f390ec Mon Sep 17 00:00:00 2001 From: erutako <167011267+erutako@users.noreply.github.com> Date: Sun, 5 Apr 2026 21:46:44 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20Best=20Time=20to=20Buy=20and=20Sell=20S?= =?UTF-8?q?tock=20=E3=81=AE2=E5=9B=9E=E7=9B=AE=E3=81=AE=E8=A7=A3=E6=B3=95?= =?UTF-8?q?=E3=83=A1=E3=83=A2=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Grind75 のテンプレートに沿い、言語化・思考記録・計算量・Ruby コード・感想を step1〜3 で記録した。 Made-with: Cursor --- .../bestTimeToBuyAndSellStock/second/step1.md | 45 +++++++++++++++++++ .../bestTimeToBuyAndSellStock/second/step2.md | 35 +++++++++++++++ .../bestTimeToBuyAndSellStock/second/step3.md | 35 +++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 grind75/bestTimeToBuyAndSellStock/second/step1.md create mode 100644 grind75/bestTimeToBuyAndSellStock/second/step2.md create mode 100644 grind75/bestTimeToBuyAndSellStock/second/step3.md diff --git a/grind75/bestTimeToBuyAndSellStock/second/step1.md b/grind75/bestTimeToBuyAndSellStock/second/step1.md new file mode 100644 index 0000000..88a4f9d --- /dev/null +++ b/grind75/bestTimeToBuyAndSellStock/second/step1.md @@ -0,0 +1,45 @@ +### やろうとしていることを言語化してみる +数字が書かれたカードが順番に並んでいて、数字の差が最大になるカードを1組み選ぶ。 +ただし、差は並び順が前のカード-後のカードでなければならない。 +その時点での最小値のカードを常にもっておく、次のカードを見るたびにそのカードとの差を計算し差が最大であれば最大値としてメモする。 + + +### 思考記録 +配列が与えられている。 +毎月1日の株価が入っている。 +購入・売却して利益を最大化したい。 +利益が得られない場合は0を返す。 + +与えられた配列をそのまま走査して、必要な情報を持っておけばO(N)でいけそうな感覚がある。 + +常に最小値は持っておきたい。 +あと、その時点での最大利益も常に持っておきたい。 +最大値はもたなくても最大利益を持っていたら良さそう。 + +### 計算量 +#### 時間計算量 +O(N) +#### 空間計算量 +O(1) + +### コード +```ruby +# @param {Integer[]} prices +# @return {Integer} +def max_profit(prices) + max = 0 + min = Float::INFINITY + prices.each do |p| + min = p if p < min + max = p - min if p - min > max + end + max +end +``` +### かかった時間 +19min + +### 感想 +- 1回目やったときの記憶が残っていた感じがある +- nilをどうするかはあんまり思いつかない。rubyで毎回nilチェックすると冗長なので、そのままエラーで良い気がする。 + - 変にデフォルトで0を返すよりはnilが来たことに気づきたい気持ち diff --git a/grind75/bestTimeToBuyAndSellStock/second/step2.md b/grind75/bestTimeToBuyAndSellStock/second/step2.md new file mode 100644 index 0000000..306deea --- /dev/null +++ b/grind75/bestTimeToBuyAndSellStock/second/step2.md @@ -0,0 +1,35 @@ +### やろうとしていることを言語化してみる + + +### 思考記録 + + +### 計算量 +#### 時間計算量 +O(N) +#### 空間計算量 +O(1) + +### コード +```ruby +# @param {Integer[]} prices +# @return {Integer} +def max_profit(prices) + max_profit = 0 + min_price = Float::INFINITY + + prices.each do |p| + min_price = [p, min_price].min + max_profit = [max_profit, p - min_price].max + end + + max_profit +end +``` +### かかった時間 +5min + +### 感想 +- step1よりも変数名を具体化してみた +- if文があるとif文の条件を頭に入れながらコードを読むのが少し大変に感じたので、min, maxで実装してみた +- 問題文を読むとlength=1は想定されているけど、0は想定されていなさそうなので空配列のときは例外投げたほうが呼び出し側は嬉しいかも \ No newline at end of file diff --git a/grind75/bestTimeToBuyAndSellStock/second/step3.md b/grind75/bestTimeToBuyAndSellStock/second/step3.md new file mode 100644 index 0000000..0f7bd22 --- /dev/null +++ b/grind75/bestTimeToBuyAndSellStock/second/step3.md @@ -0,0 +1,35 @@ +### 計算量 +#### 時間計算量 +O(N) +#### 空間計算量 +O(1) + +### コード +```ruby +# @param {Integer[]} prices +# @return {Integer} +# @raise [ArgumentError] +def max_profit(prices) + if prices.nil? || prices.empty? + raise ArugmentError, "株価データ(prices)が空です。計算には少なくとも1日以上のデータが必要です。" + end + + min_price = Float::INFINITY + max_gain = 0 + + prices.each do |p| + min_price = [min_price, p].min + max_gain = [max_gain, p - min_price].max + end + + max_gain +end +``` +### かかった時間 +5min + +### 感想 +- profitではなくgainを使ってみた + - https://github.com/TakayaShirai/leetcode_practice/pull/36/changes#r3036507957 + - 関数名を変えるとleetcode上の実行でエラーになるので、関数名はprofitのまま +- 問題の前提に沿わない入力は例外をraiseするようにしてみた \ No newline at end of file