-
Notifications
You must be signed in to change notification settings - Fork 0
122. Best Time To Sell and Buy Stock Ⅱ #44
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,188 @@ | ||
| ### Step1 | ||
|
|
||
| - 頭の中でグラフを思い浮かべた。今より前の時点のやつを売買することができる(ズル)ので、今の値と比較してどうかで決めれる | ||
| - is_havingのようなフラグ変数は管理しづらくなるだろうか。1個くらいならOK? | ||
|
|
||
| ```python | ||
| python | ||
| class Solution: | ||
| def maxProfit(self, prices: List[int]) -> int: | ||
| profit = 0 | ||
| is_having = False | ||
| prev_price = None | ||
| for price in prices: | ||
| if prev_price is None: | ||
| pass | ||
| elif is_having and prev_price > price: | ||
| profit += prev_price | ||
| is_having = False | ||
| elif not is_having and prev_price < price: | ||
| profit -= prev_price | ||
| is_having = True | ||
| prev_price = price | ||
| if is_having: | ||
| profit += prev_price | ||
| is_having = False | ||
| return profit | ||
| ``` | ||
|
|
||
| - テストケースを考える(実は今まであんまりやってなかった😅) | ||
|
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. 同じくです。自分も気をつけようと思います。 |
||
| - [] | ||
| - [5] | ||
| - [-4] (株価がマイナスはなさそう) | ||
| - [0] | ||
| - [4, 5] | ||
| - [5, 4] | ||
| - [3, 3] | ||
| - [4, 5, 4] | ||
| - [5, 4, 5] | ||
| - [4, 5, 5] | ||
| - [4, 4, 5] | ||
| - [5, 4, 4] | ||
| - [5, 5, 4] | ||
| - [0, 0, 0, 0, 0, 0, 0, 0,,,,] | ||
| - [2, 2, 2, 2,,,,,,,,] | ||
| - [4, 5, 4, 5, 4, 5, 4, 5,,,,,,,] | ||
| - [5, 4, 5, 4, 5, 4, 5, 4,,,,] | ||
| - [4, 5, 6, 5, 4, 5, 6, 5, 4,,,,,] | ||
| - [6, 5, 4, 5, 6, 5, 4, 5, 6,,,,,] | ||
| - [1, 2, 3, 4, 5, 6,,,,] | ||
| - [100, 99, 98, 97, ,,,,,,] | ||
| - くらいかな。うーん。 | ||
|
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. 自分は以前、理事の川中さんが「テストケースはシステマティックに生成すると良い」とおっしゃっていたのを参考にテストケースを考えています
Owner
Author
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. ありがとうございます。 |
||
|
|
||
|
|
||
|
|
||
| https://discord.com/channels/1084280443945353267/1210494002277908491/1210793843260133477 | ||
|
|
||
| https://github.com/fhiyo/leetcode/pull/39/files | ||
|
|
||
| [https://github.com/TORUS0818/leetcode/pull/40](https://github.com/TORUS0818/leetcode/pull/40#discussion_r1875358734) | ||
|
|
||
| - 関数を定める方法、DPでやる方法などがある | ||
| - 関数を定める方法で書いてみる | ||
| - find_next_peakとfind_next_bottomはよく似て関数だが、ここを無理やり共通化しようとするのは流石にややこしい? | ||
|
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++ には adjacent_find というのがありますね。 |
||
|
|
||
| ```python | ||
| class Solution: | ||
| def find_next_peak(self, start_index: int, nums: List[int])-> Tuple[int, int]: | ||
| assert start_index < len(nums) | ||
| i = start_index | ||
| while i + 1 < len(nums) and nums[i] <= nums[i + 1]: | ||
| i += 1 | ||
| return i, nums[i] | ||
|
|
||
| def find_next_bottom(self, start_index: int, nums: List[int])-> Tuple[int, int]: | ||
| assert start_index < len(nums) | ||
| i = start_index | ||
| while i + 1 < len(nums) and nums[i] >= nums[i + 1]: | ||
| i += 1 | ||
| return i, nums[i] | ||
|
|
||
| def maxProfit(self, prices: List[int]) -> int: | ||
| assert(len(prices) > 0) | ||
| profit = 0 | ||
| i = 0 | ||
| bought_price = prices[0] | ||
| while i < len(prices) - 1: | ||
| peak_index, peak_price = self.find_next_peak(i, prices) | ||
| profit += peak_price - bought_price | ||
| bottom_index, bottom_price = self.find_next_bottom(peak_index, prices) | ||
| i = bottom_index | ||
| bought_price = bottom_price | ||
| return profit | ||
| ``` | ||
|
|
||
| - https://github.com/hayashi-ay/leetcode/pull/56 | ||
|
|
||
| - find_next_bottom関数の返り値、indexだけの方がシンプルで良いだろうか、でも値もあった方が便利そうでむずい | ||
| - https://github.com/Ryotaro25/leetcode_first60/pull/42 | ||
| - price[i + 1] - prices[i] を変数に置いた方がいいのはなるほど | ||
| - 持ってる時、持ってない時で出す | ||
|
|
||
| ```python | ||
|
|
||
| class Solution: | ||
| def maxProfit(self, prices: List[int]) -> int: | ||
| assert(len(prices) > 0) | ||
| profit_having_stock_prev = -prices[0] | ||
| profit_not_having_stock_prev = 0 | ||
| for i in range(1, len(prices)): | ||
| profit_having_stock = max(profit_having_stock_prev, profit_not_having_stock_prev - prices[i]) | ||
| profit_not_having_stock = max(profit_not_having_stock_prev, profit_having_stock_prev + prices[i]) | ||
| profit_having_stock_prev = profit_having_stock | ||
| profit_not_having_stock_prev = profit_not_having_stock | ||
| return max(profit_having_stock_prev, profit_not_having_stock_prev) | ||
| ``` | ||
|
|
||
| ``` | ||
|
|
||
| - https://github.com/seal-azarashi/leetcode/pull/36 | ||
| - 以下のコードでも通るっぽい。簡潔ではあるが、max(profit_not_having_stock, profit_having_stock + prices[i]) の時だけprofit_having_stockが実は同時点で、ただ前の行で更新されているならば-prices[i]と+prices[i]で打ち消しあって、前時点のprofit_not_having_stockに結果的になる、という推理が必要? | ||
|
|
||
| ```python | ||
|
|
||
| class Solution: | ||
| def maxProfit(self, prices: List[int]) -> int: | ||
| assert(len(prices) > 0) | ||
| profit_having_stock= -prices[0] | ||
| profit_not_having_stock = 0 | ||
| for i in range(1, len(prices)): | ||
| profit_having_stock = max(profit_having_stock, profit_not_having_stock - prices[i]) | ||
| profit_not_having_stock = max(profit_not_having_stock, profit_having_stock + prices[i]) | ||
| return max(profit_having_stock, profit_not_having_stock) | ||
| ``` | ||
|
|
||
| - https://github.com/goto-untrapped/Arai60/pull/59 | ||
| - peakとbottomを交互にループするのは、最初にbottomをやった方が綺麗そう?気づかなかった。 | ||
|
|
||
| ```python | ||
| python | ||
|
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. 消し忘れでしょうか。
Owner
Author
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. そうですね、ありがとうございます(よくあるのでlinterとか導入したほうがいい気もしてきました) |
||
| class Solution: | ||
| def find_next_peak(self, start_index: int, nums: List[int])-> Tuple[int, int]: | ||
| assert start_index < len(nums) | ||
| i = start_index | ||
| while i + 1 < len(nums) and nums[i] <= nums[i + 1]: | ||
| i += 1 | ||
| return i, nums[i] | ||
|
|
||
| def find_next_bottom(self, start_index: int, nums: List[int])-> Tuple[int, int]: | ||
| assert start_index < len(nums) | ||
| i = start_index | ||
| while i + 1 < len(nums) and nums[i] >= nums[i + 1]: | ||
| i += 1 | ||
| return i, nums[i] | ||
|
|
||
| def maxProfit(self, prices: List[int]) -> int: | ||
| assert(len(prices) > 0) | ||
| profit = 0 | ||
| i = 0 | ||
| while i + 1 < len(prices): | ||
| bottom_i, bottom_price = self.find_next_bottom(i, prices) | ||
| peak_i, peak_price = self.find_next_peak(bottom_i, prices) | ||
| profit += peak_price - bottom_price | ||
| i = peak_i | ||
| return profit | ||
| ``` | ||
|
|
||
| - https://github.com/sakupan102/arai60-practice/pull/39 | ||
|
|
||
| https://github.com/shining-ai/leetcode/pull/38 | ||
|
|
||
| https://github.com/hroc135/leetcode/pull/36/files | ||
|
|
||
| - profit_having_stockとprofit_not_having_stockを同時に更新するというてもあるか。ただ1行が長くなって見にくくなりそう。 | ||
|
|
||
| ## Step3 | ||
|
|
||
| これが自然かな | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def maxProfit(self, prices: List[int]) -> int: | ||
| profit = 0 | ||
| for i in range(len(prices) - 1): | ||
| diff = prices[i + 1] - prices[i] | ||
| if diff > 0: | ||
| profit += diff | ||
|
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. ifを消して
Owner
Author
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. 確かに。ありがとうございます。 |
||
| return profit | ||
| ``` | ||
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.
if prev_price is None:を使うのはループの1回目だけだと思いますので、prev_priceをprice[0]で初期化するのもアリかと思いました。prices空の場合の制御は必要になりますがループ内のコードは短くなると思います。
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.
ループの方をprice[1]からスタートする感じでしょうか。
確かにその方がシンプルですね