-
Notifications
You must be signed in to change notification settings - Fork 0
1011. Capacity To Ship Packages Within D Days #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,109 @@ | ||
| ## 何も見ずに解いてみる | ||
|
|
||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| int shipWithinDays(vector<int>& weights, int days) { | ||
| int capacity_min = *max_element(weights.begin(), weights.end()); | ||
| int capacity_max = accumulate(weights.begin(), weights.end(), 0); | ||
| while (capacity_min < capacity_max) { | ||
| int capacity_mid = capacity_min + (capacity_max - capacity_min) / 2; | ||
| if (can_ship(weights, days, capacity_mid)) { | ||
| capacity_max = capacity_mid; | ||
| } | ||
| else { | ||
| capacity_min = capacity_mid + 1; | ||
| } | ||
| } | ||
| return capacity_min; | ||
| } | ||
| private: | ||
| bool can_ship(vector<int>& weights, int days, int capacity) { | ||
|
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. 複合型で、関数の内部で変更されない変数の型には const を付けることをおすすめします。ついていないと、読み手が、変数が関数内で変更されることを前提に読んでしまい、混乱してしまう場合があると思います。 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++ では関数名を lower_snake とするのは、あまり見ないように思います。 UpperCamel をよく見かけます。 参考までにスタイルガイドへのリンクを貼ります。 https://google.github.io/styleguide/cppguide.html#Function_Names
上記のスタイルガイドは唯一絶対のルールではなく、複数あるスタイルガイドの一つに過ぎないということを念頭に置くことをお勧めします。また、所属するチームにより何が良いとされているかは変わります。自分の中で良い書き方の基準を持ちつつ、チームの平均的な書き方で書くことをお勧めいたします。
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. ありがとうございます。leetcodeのテンプレートに設定されているデフォルトに合わせてlowerCamelで書いてみます。 |
||
| int current_day = 1; | ||
| int load = 0; | ||
| for (int weight : weights) { | ||
| if (load + weight <= capacity) { | ||
| load += weight; | ||
| } | ||
|
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. continue して else のインデントを下げたいと思いました。 |
||
| else { | ||
| if (weight > capacity) { | ||
|
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. このチェックは for 文の先頭にあっても良いかなと思いました。
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. 迷いました。実世界で手作業で船に積んでいくとしたらどういう順番でチェックするだろうか、ということを考えてここに置いてみましたが、最初に置いてもいいと思います。 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 false; | ||
| } | ||
| current_day += 1; | ||
| if (current_day > days) { | ||
| return false; | ||
| } | ||
| load = weight; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| ## 他の人のコードを見てみる | ||
|
|
||
| https://github.com/tokuhirat/LeetCode/pull/44/files | ||
| https://github.com/ryosuketc/leetcode_arai60/pull/33/files | ||
| https://github.com/Ryotaro25/leetcode_first60/pull/51/files | ||
| https://github.com/goto-untrapped/Arai60/pull/41/files | ||
|
|
||
| ## 最終コード | ||
|
|
||
| weightsとdaysをキャプチャしたいと思ったのでラムダ式で書いてみました。 | ||
|
|
||
| ```cpp | ||
| if (++current_day > days) { | ||
| // ... | ||
| } | ||
| ``` | ||
| の部分は | ||
| ```cpp | ||
| ++current_day; | ||
| if (current_day > days) { | ||
| // ... | ||
| } | ||
| ``` | ||
| の方が一般的なんですかね?調べた感じどっちも結構ありそうでした。 | ||
|
|
||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| int shipWithinDays(vector<int>& weights, int days) { | ||
| auto can_ship = [&weights, days](int capacity) -> bool { | ||
|
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. 数行を超えるラムダ関数は、ネストが深くなったり、ラムダ関数の前後を追う際に目の移動量が多くなったりと、読みにくく感じます。メンバ関数にくくりだしたほうが良いと思います。 並列計算フレームワークに渡すロジックを記述する際や、 UI のイベントハンドラーを大量に書かなければならない場合等、ラムダ関数にせざるを得ない場合もあるとは思います。 |
||
| int current_day = 1; | ||
|
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. currentというよりは所要日数の方が実態に近いかと思いました。required_daysなどどうでしょうか。
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. そちらの方がわかりやすいかもしれませんね。実際に積んでいく状況をイメージして書くのと、もしも積んでいったらどれぐらい必要だろうか、という計算をするイメージで書くので変わってくるかもしれません。(自分は前者のイメージでした) |
||
| int load = 0; | ||
| for (int weight : weights) { | ||
| if (load + weight <= capacity) { | ||
| load += weight; | ||
|
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. continue して else のネストをなくしたい気がします (全体的にネストが深いので)。 |
||
| } | ||
| else { | ||
| if (weight > capacity) { | ||
| return false; | ||
|
Comment on lines
+81
to
+82
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 (++current_day > days) { | ||
|
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 false; | ||
| } | ||
| load = weight; | ||
| } | ||
| } | ||
| return true; | ||
| }; | ||
|
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. 冒頭に書かれたコードの方が読みやすかったです。少なくともここに空行があると良いかなと思います。 |
||
| int low = *max_element(weights.begin(), weights.end()); | ||
| int high = accumulate(weights.begin(), weights.end(), 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. c++17から reduce というものがあるそうです。
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. どっちでもいいかなと思ってたのですが、色々見てみると今回はreduceのほうが良さそうですね!ありがとうございます。 |
||
| while (low < high) { | ||
| int mid = low + (high - low) / 2; | ||
| if (can_ship(mid)) { | ||
| high = mid; | ||
| } | ||
| else { | ||
| low = mid + 1; | ||
| } | ||
| } | ||
| return low; | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| `current_day`を`0`で初期化してしまい一敗・・・ | ||
| `1`から始める方が現実世界の考え方には即しているような気がするのでこのままにします | ||
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.
ただの感想なんですが、C++ってsum()がないんですね
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.
最大値を探すものはstd::max_elementというのがありますが、sumは直接的なものはないようです。