121. Best Time to Buy and Sell Stock#37
Conversation
| } | ||
|
|
||
| int current_min_price = prices[0]; | ||
| int current_max_return = prices[0] - prices[0]; |
There was a problem hiding this comment.
売り買いのニュアンスがわかるように、という意図を込めたんですが、0でも伝わりますかね。
There was a problem hiding this comment.
問題文では、同日での売り買いはできないように読めました。
You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.
| int current_min_price = prices[0]; | ||
| int current_max_return = prices[0] - prices[0]; | ||
|
|
||
| for (int i = 0; i < prices.size(); ++i) { |
There was a problem hiding this comment.
1から始めても一応動きますかね。
あと、ご存知かもしれませんがfor (int price : prices) {}という書き方もできます。僕はこっちの方が好みかもしれません。
https://cpprefjp.github.io/lang/cpp11/range_based_for.html
There was a problem hiding this comment.
ありがとうございます。確かに、range based for の方が見やすいかもしれないと思いました。
| return 0; | ||
| } | ||
|
|
||
| int current_min_price = prices[0]; |
There was a problem hiding this comment.
current_min_price と current_max_return は、 current_ を外しても十分に意味が伝わると思いました。
|
|
||
| - `prices.length < 10^5` なので $O(N^2)$ の全探索はきついだろうからパス。 | ||
| - 分割統治:割って左側だけ、右側だけ、クロスの最大値を計算し最も大きいものを返していく。時間計算量 $O(N \log N)$、空間計算量 $O(\log N)$。`step1.cpp` はこれで書いた。 | ||
| - もっと早いやり方があるっぽいが。 |
| return _helper(prices, 0, prices.size() - 1); | ||
| } | ||
| private: | ||
| int _helper(const std::vector<int>& prices, int start, int end) { |
There was a problem hiding this comment.
end は最後の要素 の次 を指すことが多いように思います(つまり prices[end] は値が入っていない)。start (first), last の方がここでの用法を適切に表現しているように感じます。
| int min_left = prices[start]; | ||
| for (int i = start; i <= mid; i++) { | ||
| min_left = std::min(min_left, prices[i]); | ||
| } | ||
|
|
||
| int max_right = prices[mid]; | ||
| for (int i = mid + 1; i <= end; i++) { | ||
| max_right = std::max(max_right, prices[i]); | ||
| } |
There was a problem hiding this comment.
ここは何をやっているのか分かりやすいように(mid をまたぐ場合の最大利益を求めているのですよね)、結果を一時変数に入れる(max_return_crossing_midとか)、さらにサブルーチンに切る、コメントで補足する、などしたいです。
| for (int i = start; i <= mid; i++) { | ||
| min_left = std::min(min_left, prices[i]); | ||
| } |
There was a problem hiding this comment.
mini_element()を用いて
| for (int i = start; i <= mid; i++) { | |
| min_left = std::min(min_left, prices[i]); | |
| } | |
| min_left = *std::min_element(first, mid); |
などとするのはいかがでしょうか.(_helper()の引数をint startからForwardIterator firstなどのように変更するか,*std::min_element(prices.begin() + start, prices.begin() + mid)`のようにする必要はありますが)
| current_max_return = std::max(current_max_return, prices[i] - current_min_price); | ||
| } | ||
|
|
||
| return std::max(current_max_return, 0); |
There was a problem hiding this comment.
current_max_returnの初期値が0なのでstd::maxを用いた更新で負になることはないため,return current_max_returnで良いと感じました.
(あえて明示することで伝わりやすくするという意図もあるかもしれませんが,)
問題
https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/
次の問題
122. Best Time to Buy and Sell Stock 2