Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions 1011/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 1011. Capacity To Ship Packages Within D Days

https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/description/

TODO: 二分探索を自分で書く

- capacityを指定すればそれが可能かはO(N)で判定できる
- 上限をどのように定めるかが問題。単純にsum(weights)としたとき220ms、minを使ったとき119msとなった。
- 問題のWeight上限を使う方法は正攻法なのだろうか
- 自力で解法を思いついたが、二分探索のヒントがあったから

n = len(weights), M = maximum_valueとすると
- 時間計算量: O(n*log(M))
- 空間計算量: O(1) (入力は含めない)


コメント集に該当箇所はない

https://github.com/naoto-iwase/leetcode/pull/27/changes

capacityの下限はmax(weights)とできるのか
- これを反映してsol2.pyとしたが、149msとなり逆に遅くなった
- maxをとるO(n)の操作に余分な時間がかかるケースが多いのだろう。二分探索は途中で打ち切られるのでそれほど重くない。


https://github.com/mamo3gr/arai60/blob/1011_capacity-to-ship-packages-within-d-days/1011_capacity-to-ship-packages-within-d-days/memo.md

色々なコードがまとめられている

https://github.com/h1rosaka/arai60/pull/46/changes

上でも述べられているけど、 `for _ in range(days):` で書くこともできるのは思いつかなかった
23 changes: 23 additions & 0 deletions 1011/sol1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import bisect

MAXIMUM_WEIGHT = 500


class Solution:
def shipWithinDays(self, weights: list[int], days: int) -> int:
def can_ship(capacity):
used_days = 1
shipped_weight_on_current_day = 0
for weight in weights:
if shipped_weight_on_current_day + weight <= capacity:
shipped_weight_on_current_day += weight
continue
used_days += 1
if used_days > days or weight > capacity:
return False
shipped_weight_on_current_day = weight
return True

maximum_value = min(sum(weights), MAXIMUM_WEIGHT * (len(weights) // days + 1))

return bisect.bisect_left(range(1, maximum_value), True, key=can_ship) + 1
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

すでに 35.search insert position で練習済みかと思いますが、二分探索を自力で実装するのがこの問題の期待値なのかなと思いました。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほど。もう一度復習する予定なので、そのときに書き直してみます。

25 changes: 25 additions & 0 deletions 1011/sol2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import bisect


class Solution:
def shipWithinDays(self, weights: list[int], days: int) -> int:
def can_ship(capacity):
used_days = 1
shipped_weight_on_current_day = 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

個人的にはここの変数名はtotal_weightとかで充分だと思いました。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確かに長いですね。
「変数名は省略するな」を意識していたのですが、「長くて良い」という意味ではないので冗長にならないように気をつけます。

for weight in weights:
if shipped_weight_on_current_day + weight <= capacity:
shipped_weight_on_current_day += weight
continue
used_days += 1
if used_days > days or weight > capacity:
return False
shipped_weight_on_current_day = weight
return True

minimum_value = max(weights)
maximum_value = sum(weights)

return (
bisect.bisect_left(range(minimum_value, maximum_value), True, key=can_ship)
+ minimum_value
)
25 changes: 25 additions & 0 deletions 1011/sol2_revised.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import bisect


class Solution:
def shipWithinDays(self, weights: list[int], days: int) -> int:
def can_ship(capacity):
used_days = 1
total_weight = 0
for weight in weights:
if total_weight + weight <= capacity:
total_weight += weight
continue
used_days += 1
if used_days > days or weight > capacity:
return False
total_weight = weight
return True

minimum_value = max(weights)
maximum_value = sum(weights)

return (
bisect.bisect_left(range(minimum_value, maximum_value), True, key=can_ship)
+ minimum_value
)