-
Notifications
You must be signed in to change notification settings - Fork 0
1011. Capacity To Ship Packages Within D Days #46
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,189 @@ | ||
| # Step1 | ||
|
|
||
| かかった時間:33min | ||
|
|
||
| 計算量:N = len(weights), M = sum(weights)として | ||
|
|
||
| 時間計算量:O(NlogM) | ||
|
|
||
| 空間計算量:O(1) | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def shipWithinDays(self, weights: List[int], days: int) -> int: | ||
| def can_ship_capacity_in_days(capacity: int, days: int) -> bool: | ||
| total_weight = 0 | ||
| i = 0 | ||
| while days: | ||
| if total_weight + weights[i] > capacity: | ||
| total_weight = 0 | ||
| days -= 1 | ||
| continue | ||
|
|
||
| total_weight += weights[i] | ||
| i += 1 | ||
| if i == len(weights): | ||
| return True | ||
|
Comment on lines
+17
to
+26
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. こう書くなら、個人的にはこう変形した方がわかりやすい気がしています while days:
if i == len(weights):
return True
if total_weight + weights[i] > capacity:
total_weight = 0
days -= 1
total_weight += weights[i]
i += 1
return False |
||
|
|
||
| return False | ||
|
|
||
| left = 1 | ||
| right = sum(weights) | ||
| while left < right: | ||
| middle = (left + right) // 2 | ||
| if can_ship_capacity_in_days(middle, days): | ||
| right = middle | ||
| else: | ||
| left = middle + 1 | ||
|
|
||
| return left | ||
| ``` | ||
| 思考ログ: | ||
| - 問題を読み違えて時間を無駄にしていた(weightsの順序を保つ制約を無視していた) | ||
| - 二分探索の探索用変数の名前を横着している、step2以降なんとかする | ||
| - 類似の問題を昔解いたのを覚えていた | ||
| - あるcapacityにした時、days内で輸送できるか考える | ||
| - capacity = sum(weights)とすれば、必ず1日で輸送できる | ||
| - 輸送できるcapacityのうち最小のものを探す | ||
| - [輸送できない, 輸送できない, ..., 輸送できない, (輸送できる], 輸送できる, ... ,輸送できる] | ||
|
|
||
| # Step2 | ||
|
|
||
| 講師役目線でのセルフツッコミポイント: | ||
| - weights=[], days=0の時は? | ||
|
|
||
| 参考にした過去ログなど: | ||
| - https://github.com/saagchicken/coding_practice/pull/15 | ||
| - 探索範囲は1からでなくmax(weights)からでいい | ||
| - https://github.com/saagchicken/coding_practice/pull/10 | ||
| - https://github.com/olsen-blue/Arai60/pull/44 | ||
| - https://github.com/hroc135/leetcode/pull/42 | ||
| - goのbinary-searchの実装 | ||
| - https://github.com/Ryotaro25/leetcode_first60/pull/51 | ||
| - Makefileについて | ||
| - https://github.com/Mike0121/LeetCode/pull/46 | ||
| - https://github.com/Yoshiki-Iwasa/Arai60/pull/37 | ||
| - https://github.com/rossy0213/leetcode/pull/26 | ||
| - https://github.com/goto-untrapped/Arai60/pull/41 | ||
| - https://github.com/fhiyo/leetcode/pull/45 | ||
| - https://github.com/fhiyo/leetcode/pull/45/files#r1682470839 | ||
| - https://github.com/sakupan102/arai60-practice/pull/45 | ||
| - https://github.com/SuperHotDogCat/coding-interview/pull/27 | ||
| - https://github.com/SuperHotDogCat/coding-interview/pull/27/files#r1631399685 | ||
| - 命名はなかなか難しいなと | ||
| - 実態を表すよう無理に情報を詰め込むと拗らせるので、そういう場合はなるべくシンプルにして、必要ならコメント補足を心掛ける | ||
| - https://github.com/YukiMichishita/LeetCode/pull/10 | ||
| - bisect_left/right | ||
| - bisect_rightを勘違いしていた(等号は含まない) | ||
|
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. bisect_right は、「昇順になるように挿入するとしたら可能な範囲の中で一番右の位置」を見つけてきますね。 |
||
| - https://docs.python.org/ja/3.13/library/bisect.html | ||
| > all(elem > x for elem in a[ip : hi]) is true for the right slice. | ||
| - https://github.com/shining-ai/leetcode/pull/44 | ||
| - https://github.com/hayashi-ay/leetcode/pull/55 | ||
|
|
||
| 所要日数を計算する | ||
| ```python | ||
| class Solution: | ||
| def shipWithinDays(self, weights: List[int], days: int) -> int: | ||
| assert days > 0 | ||
| if not weights: | ||
| return 0 | ||
|
|
||
| def calculate_shipping_days(capacity: int) -> int: | ||
|
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. calculate良いですが、わたしならget_days_requiredとかにするかもしれません 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. 同意です。 他の方が書かれていた、所用日数を計算する、という選択肢が頭になかったので書いてみました。 |
||
| total_weight = 0 | ||
| days_required = 1 | ||
| for weight in weights: | ||
| if total_weight + 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. このコードの場合、lowの初期値が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. この場合だと日付を求めているので、返すのはinfとかsys.maxintですかね |
||
| total_weight = 0 | ||
| days_required += 1 | ||
|
|
||
| total_weight += weight | ||
|
|
||
| return days_required | ||
|
|
||
| low = max(weights) | ||
| high = sum(weights) | ||
| while low < high: | ||
| candidate_capacity = (low + high) // 2 | ||
| if calculate_shipping_days(candidate_capacity) <= days: | ||
| high = candidate_capacity | ||
| else: | ||
| low = candidate_capacity + 1 | ||
|
|
||
| return low | ||
| ``` | ||
| 思考ログ: | ||
|
|
||
| bisect_right(練習) | ||
| ```python | ||
| class Solution: | ||
| def shipWithinDays(self, weights: List[int], days: int) -> int: | ||
| assert days > 0 | ||
| if not weights: | ||
| return 0 | ||
|
|
||
| def can_ship(capacity: int) -> bool: | ||
| total_weight = 0 | ||
| days_required = 1 | ||
| for weight in weights: | ||
| if total_weight + weight > capacity: | ||
| total_weight = 0 | ||
| days_required += 1 | ||
|
|
||
| total_weight += weight | ||
|
Comment on lines
+127
to
+132
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 の中に計算式があるのは、なんか変な感じがしました。 total_weight は思考の中心にあるコップみたいなものだと思うんですよね。もうちょい上のほうに書いてあげたいです。
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 days_required <= days | ||
|
|
||
| return bisect.bisect_right( | ||
| range(sum(weights) + 1), | ||
| False, | ||
| lo=max(weights), | ||
| hi=sum(weights) + 1, | ||
| key=can_ship | ||
| ) | ||
| ``` | ||
| 思考ログ: | ||
| - 今回の課題で敢えて使うこともないが、bisect_rightの練習で書いてみた | ||
| - 関数名、```can_ship```くらいでいい気もするので少し変更 | ||
|
|
||
| # Step3 | ||
|
|
||
| かかった時間:5min | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def shipWithinDays(self, weights: List[int], days: int) -> int: | ||
| assert days > 0 | ||
| if not weights: | ||
| return 0 | ||
|
|
||
| def can_ship(capacity: int) -> bool: | ||
| total_weight = 0 | ||
| days_required = 1 | ||
| for weight in weights: | ||
| 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. そうですよね、bisectでrangeをつかうならこの例外処理が必要になると思います 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. lo= を書いているので、なくても動くかとは思いますが、しかし書いたほうが読みやすいでしょうね。後々変更が入ったときにバグの原因にもなりそうですし。 |
||
| return False | ||
|
|
||
| if total_weight + weight > capacity: | ||
| total_weight = 0 | ||
| days_required += 1 | ||
|
|
||
| total_weight += weight | ||
|
|
||
| return days_required <= 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. 私はdays requiredがdaysを超えた時点で弾きたくなります |
||
|
|
||
| return bisect.bisect_left( | ||
| range(sum(weights)), | ||
| True, | ||
| key=can_ship, | ||
| lo=max(weights), | ||
| hi=sum(weights) | ||
| ) | ||
| ``` | ||
| 思考ログ: | ||
| - ```weight > capacity```の早期リターンを追加 | ||
|
|
||
| # Step4 | ||
|
|
||
| ```python | ||
| ``` | ||
| 思考ログ: | ||
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.
iはちょっとわかりにくい気がします
weight_index
とかどうでしょうか
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.
for i in range(len(array)):と書かれたら、i が array の添字だと思うと思うんですね。これを長々と説明的に書かれてもありがたくないのです。あと、この for を抜けたらもう忘れて良いやつだというのが暗に含意されています。これが、
for first_zero_index inだったら途中で見つけて break するから抜けても覚えている必要があるものでしょう。https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.fcs3httrll4l
下でも書いていますが、weights で回すほうが多分素直なんでしょうね。