-
Notifications
You must be signed in to change notification settings - Fork 0
122. Best Time to Buy and Sell Stock II #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
start_new_problem.sh | ||
main.go | ||
go.mod | ||
go.sum | ||
*.go |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
問題: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/ | ||
|
||
### Step 1 | ||
- 購入価格を覚えておき、次の日に株価が下がるなら売って次の日に買う | ||
- 方針はすぐに思いついたが、末尾要素の扱いに手こずった | ||
- テストケース | ||
- [0] -> 0 | ||
- [0,0] -> 0 | ||
- [0,1] -> 1 | ||
- [1,0] -> 0 | ||
- [0,1,2,0,2] -> 4 | ||
- [1,0,1,0,1] -> 2 | ||
- [2,0,2,1,0] -> 2 | ||
|
||
```Go | ||
func maxProfit(prices []int) int { | ||
purchasedPrice := prices[0] | ||
res := 0 | ||
for i := 0; i < len(prices)-1; i++ { | ||
// When to sell | ||
if prices[i] > prices[i+1] { | ||
res += prices[i] - purchasedPrice | ||
purchasedPrice = prices[i+1] | ||
} | ||
} | ||
res += max(0, prices[len(prices)-1]-purchasedPrice) | ||
return res | ||
} | ||
``` | ||
|
||
### Step 2 | ||
#### 2a | ||
- 前日から上がったらその差分を累積していく考え方 | ||
- 実装がシンプルになる | ||
- 前日より株価が上がったらすぐ売っているというのがちょっと現実に即さない感じはある | ||
|
||
```Go | ||
func maxProfit(prices []int) int { | ||
accumulatedProfit := 0 | ||
for i := 1; i < len(prices); i++ { | ||
if prices[i-1] < prices[i] { | ||
accumulatedProfit += prices[i] - prices[i-1] | ||
} | ||
} | ||
return accumulatedProfit | ||
} | ||
``` | ||
|
||
#### 2b | ||
- 株を持っている状態と持っていない状態それぞれの場合の最良の収支を更新していく方法 | ||
- 理解するのにかなり時間がかかった | ||
- profitWithStockがマイナスになる部分の理解に苦しんだ | ||
- 参考 | ||
- https://github.com/fhiyo/leetcode/pull/39#pullrequestreview-216579962 | ||
- https://github.com/goto-untrapped/Arai60/pull/59/files#diff-c59f6e68b39b5b00cc1d1fd0ff30aa94e7e2a882d9daefdfb73eda1b94fb3e17R53-R54 | ||
|
||
``` | ||
入力: [7,1,5,3,6,4] | ||
-7 -1 -> -1 1 -> 1 3 | ||
↗︎ ↓ ↗️ ↓ ↗️ | ||
0 -> 0 4 -> 4 7 -> 7 | ||
|
||
上がprofitWithStock、下がprofitWithoutStock | ||
``` | ||
|
||
```Go | ||
func maxProfit(prices []int) int { | ||
profitWithStock := -prices[0] | ||
profitWithoutStock := 0 | ||
for i := 1; i < len(prices); i++ { | ||
profitWithStock = max(profitWithStock, profitWithoutStock-prices[i]) | ||
profitWithoutStock = max(profitWithoutStock, profitWithStock+prices[i]) | ||
} | ||
return profitWithoutStock | ||
} | ||
``` | ||
|
||
### Step 3 | ||
|
||
```Go | ||
func maxProfit(prices []int) int { | ||
res := 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 個人的には変に省略語を使わず (Goの慣習だったらすいません) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. resやresult以外で名前をつけるとしたらmaxProfitかなと思いましたが、関数名と被るので避けました
とあるので関数名をgetMaxProfit、変数名をmaxProfitにするのも微妙かなと思いました。 |
||
for i := 1; i < len(prices); i++ { | ||
if prices[i-1] < prices[i] { | ||
res += prices[i] - prices[i-1] | ||
} | ||
} | ||
return res | ||
} | ||
``` | ||
|
||
### CS | ||
- Rust | ||
- なんで人気なんだろうと気になった | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 仕事で使うんですが、コンパイラがかなり賢くて関数型言語っぽい型計算ができたりします There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. C/C++と比べて型推論に任せられる場面が多いということですか?(RustはC/C++と比較されることが多いと感じたので引き合いに出してみました) |
||
- C/C++に比べてメモリの管理がしやすい | ||
- ガベージコレクションの代わりにオーナーシップという手法を用いている | ||
- 組み込みシステム開発などの低レイヤーでよく使われる | ||
- 参考: https://github.blog/developer-skills/programming-languages-and-frameworks/why-rust-is-the-most-admired-language-among-developers/ | ||
- トップダウン vs ボトムアップ | ||
- ソフトウェア工学における設計戦略 | ||
- トップダウン: 全体を決めてから詳細を決める | ||
- ボトムアップ: 個々の部品を作り、それらを集積して全体を作る | ||
- 参考: https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%83%E3%83%97%E3%83%80%E3%82%A6%E3%83%B3%E8%A8%AD%E8%A8%88%E3%81%A8%E3%83%9C%E3%83%88%E3%83%A0%E3%82%A2%E3%83%83%E3%83%97%E8%A8%AD%E8%A8%88 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
これでも結果的には問題がないですが、本当は、この2変数は同時に更新したほうが意味としては自然に思います。
profitWithStock (株を持った状態で夜を越すときの持ち金の最大値。)
profitWithoutStock (株を持たない状態で夜を越すときの持ち金の最大値。)
なのだから、「前日、株を持った状態で夜を越すときの持ち金の最大値 + 株を売った利益」としたほうが自然に思います。結果的にはこれでもいいのですが。(それとも自然な解釈がありますでしょうか。)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
あるいは
ということですね。たしかに前日の値を元に当日の値を更新した方が自然ですね