Create 0_121. Best Time to Buy and Sell Stock.md#40
Create 0_121. Best Time to Buy and Sell Stock.md#40irohafternoon wants to merge 1 commit intomainfrom
Conversation
huyfififi
left a comment
There was a problem hiding this comment.
良いと思います!コードもわかりやすく、引っかかるところもなかったです!
| #include <vector> | ||
|
|
||
| class Solution { | ||
| public: int maxProfit(const std::vector < int > & prices) { |
There was a problem hiding this comment.
さらっと Google C++ Style GuideとLLVM Coding Standardsをざっと眺めると、std::vector<int>& pricesと、vector, <, int周りにスペースがない方が一般的なのかな?と思います。私自身もスペースがあるスタイルは見た記憶はないですね。C++に明るくないので、私の感覚が誤っている可能性は否めませんが😅
ところで、広く使われているC++のformatterとかあるのでしょうか 🤔 広く許容されるスタイル感覚が身につくまで、formatter・linterを使用するのは1つの手段ですよね。
There was a problem hiding this comment.
ありがとうございます。LeetCode上で書いたものをこのgithubに転記すると、インデントがおかしくなる事象があったので、最後にフォーマッターを使ったのですが、そこであまり見られない形になってしまったことに気づきませんでした。
https://www.codexize.com/tools/cpp-formatter
このサイトなどは一般的な形に整えられるようなので、こちらを使うことに統一しようと思います
There was a problem hiding this comment.
C++ はパースするためには include 含め頭から読む必要があります。
型か分からないと整形も難しいんですね。。
| 4分,4分,4分で3回Accept | ||
|
|
||
| #### 2周目の宿題 | ||
| - C++のクラスについて理解を深める(仮装関数,this,継承など) |
|
|
||
|
|
||
| 計算量 | ||
| - 時間計算量 O(N) N = 10^5ステップの時 10マイクロ秒 |
There was a problem hiding this comment.
実行時間は環境によって変わりそうなので、手元の環境ならそう明記した方が厳密かもしれませんね。
There was a problem hiding this comment.
ありがとうございます。手元の値でなく、一般的にc++の計算ステップを10^9回/秒と概算したときの値の見積もりで、その旨明記するべきでした
There was a problem hiding this comment.
1e5 / 1e9 = 1e-4 = 100マイクロ秒ではないでしょうか?
また、C++の計算ステップ数は1e8回/秒と見積もった方が正確になるかもしれません。
https://discordapp.com/channels/1084280443945353267/1262688866326941718/1346058939674005575
There was a problem hiding this comment.
この場合のループは、私の推測では30クロックかからないと思います。
タイトなループの部分を見ると、
prices[i] を取ってくる、引き算、max, min で回りますね。
x86 では、LEA で取ってきて、SUB で引き算。max, min については CMOVcc という命令があって、CMP で比較した後のフラグで代入の有無を決められます。分岐予測もできそうです。
よって、10命令以下で回りそうです。
(ARM は CSEL があるようです。)
なので、この場合は、1e9 でもいけそうと感じます。(間違っているかもしれません。測ってみてください。)
There was a problem hiding this comment.
@hroc135 @oda
レビューありがとうございます。また返信が遅くなりすみません。
1e5 / 1e9 = 1e-4 = 100マイクロ秒ではないでしょうか?
こちらは記載誤りでした。指摘ありがとうございます。
実行時間については今まで測ったことがなかったので調べながら実行してみました。
環境は個々ののPCだと再現性が低いかなと思い、オンライン上の環境を使用しました。
https://paiza.io/ja/projects/new
計測はstd::chronoを使用しています
#include <iostream>
#include <chrono>
#include <algorithm>
#include <vector>
#include <random>
class Solution {
public: int maxProfit(const std::vector < int > & prices) {
if (prices.empty()) {
return 0;
}
int max_profit = 0;
int lowest_price_ever = prices[0];
for (int i = 1; i < prices.size(); i++) {
// 昨日までの最安値の今日の値を比べる
max_profit = std::max(max_profit, prices[i] - lowest_price_ever);
lowest_price_ever = std::min(lowest_price_ever, prices[i]);
}
return max_profit;
}
};
int main() {
// LeetCodeの制限と同じ制限で各priceの値は0以上10^4以下
int price_limit = 10000;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distrib(0, price_limit);
//乱数で入力のpricesを作成、配列のサイズは10^5
int size = 100000;
std::vector <int> prices;
for (int i = 0; i < size ; ++i) {
int random_number = distrib(gen);
prices.push_back(random_number);
}
Solution sol;
// 測定開始
auto start = std::chrono::high_resolution_clock::now();
// 測定部分
int result = sol.maxProfit(prices);
// 測定終了
auto end = std::chrono::high_resolution_clock::now();
std::cout << result << std::endl;
// 経過時間を計算
// std::chrono::duration_cast<std::chrono::nanoseconds> を使用してナノ秒単位に変換
auto duration_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
double time = duration_ns.count();
// 結果の表示
std::cout << "処理にかかった時間: " << time << " ナノ秒" << std::endl;
std::cout << "1回当たり"<< time / size << "ナノ秒かかる"<< endl;
return 0;
}これを実行すると、サイズ10000の配列に対して結果が
処理にかかった時間: 84083 ナノ秒
1回当たり0.84083ナノ秒かかる
のようになりました。1回当たり1ナノ秒を切っているので、一秒間に1e9回以上回すことが可能のようです。
There was a problem hiding this comment.
備忘:
std::chrono
https://cpprefjp.github.io/reference/chrono.html
std::random
https://cpprefjp.github.io/reference/random.html
| return 0; | ||
| } | ||
| int max_profit = 0; | ||
| int lowest_price_ever = prices[0]; |
|
|
||
|
|
||
| - ドキュメント系 | ||
|
|
There was a problem hiding this comment.
【追記】
std::numeric_limits
https://cpprefjp.github.io/reference/limits/numeric_limits.html
| throw std::invalid_argument("Price cannot be negative"); | ||
| } | ||
| if (prices[i] < lowest_price_ever) { | ||
| lowest_price_ever = prices[i]; |
This Problem
Best Time to Buy and Sell Stock
Next Problem
Best Time to Buy and Sell Stock II