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
28 changes: 28 additions & 0 deletions 0875.Koko-Eating-Bananas/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# 875. Koko Eating Bananas

## step1
二分探索を思いつく。時間計算量はO(nlog max(piles))。17mほど。最小値と最大値を何度か間違えた(ガチャを引いてしまった)。

とりあえず書いた答えを残す。

改善する。

上限と下限を単純に 1, max(piles)とした方が可読性が上がるが、速度は落ちる。

## step2
二分探索を手で書く

https://leetcode.com/problems/koko-eating-bananas/solutions/7047251/simple-solution-by-harshita_114-3c0a/

can_eat_all の判定はfor文を使えば早期終了できる場合があるのか

実際の実行時間はジェネレータ表記の方が早かった

https://github.com/yamashita-ki/codingTest/pull/15

https://github.com/Exzrgs/LeetCode/pull/45/changes

https://github.com/TaisukeFujise/leetcode_tafujise/pull/16

## step3
今回は省略で良いだろう
16 changes: 16 additions & 0 deletions 0875.Koko-Eating-Bananas/step1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import bisect


class Solution:
def minEatingSpeed(self, piles: List[int], h: int) -> int:
def can_eat_all(k):
return sum(((pile + k - 1) // k for pile in piles)) <= h

candidate = range(
max(min(piles) // h, 1),
max((max(piles) * 2 - 1) // (h // len(piles)), 1) + 1,
)
index = bisect.bisect_left(
range(len(candidate)), True, key=lambda index: can_eat_all(candidate[index])
)
return candidate[index]
18 changes: 18 additions & 0 deletions 0875.Koko-Eating-Bananas/step1_revised.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import bisect


class Solution:
def minEatingSpeed(self, piles: list[int], h: int) -> int:
if not piles:
return 0

def can_eat_all(k):
return sum(((pile + k - 1) // k for pile in piles)) <= h

max_candidate = max((max(piles) * 2 - 1) // (h // len(piles)), 1)
min_candidate = max(min(piles) // h, 1)
candidate = range(min_candidate, max_candidate + 1)
index = bisect.bisect_left(
range(len(candidate)), True, key=lambda index: can_eat_all(candidate[index])
)
return candidate[index]
18 changes: 18 additions & 0 deletions 0875.Koko-Eating-Bananas/step2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Solution:
def minEatingSpeed(self, piles: list[int], h: int) -> int:
if not piles:
return 0

def can_eat_all(k):
return sum(((pile + k - 1) // k for pile in piles)) <= h

left = max(min(piles) // h, 1)
right = max((max(piles) * 2 - 1) // (h // len(piles)), 1) + 1
while left < right:
mid = left + (right - left) // 2

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Python の int は格納できる数値の大きさに実質上限がないため、オーバーフローを回避する書き方はしなくてよいと思います。

mid = (left + right) // 2

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.

今後はそのように書こうと思います。
他の言語や numpy を使用する場合を想定していましたが、この場合は不要ですね。

if not can_eat_all(mid):
left = mid + 1
else:
right = mid

return left
23 changes: 23 additions & 0 deletions 0875.Koko-Eating-Bananas/step2_early_return.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Solution:
def minEatingSpeed(self, piles: list[int], h: int) -> int:
if not piles:
return 0

def can_eat_all(k):
hours = 0
for i, pile in enumerate(piles):
hours += (pile + k - 1) // k
if hours + (len(piles) - i - 1) > h:
return False
return True

left = max(min(piles) // h, 1)
right = max((max(piles) * 2 - 1) // (h // len(piles)), 1) + 1
while left < right:
mid = left + (right - left) // 2
if not can_eat_all(mid):
left = mid + 1
else:
right = mid

return left
18 changes: 18 additions & 0 deletions 0875.Koko-Eating-Bananas/step2_revised.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Solution:
def minEatingSpeed(self, piles: list[int], h: int) -> int:
if not piles:
return 0

def can_eat_all(k):
return sum(((pile + k - 1) // k for pile in piles)) <= h

left = max(min(piles) // h, 1)
right = max((max(piles) * 2 - 1) // (h // len(piles)), 1) + 1
while left < right:
mid = (left + right) // 2
if not can_eat_all(mid):
left = mid + 1
else:
right = mid

return left