Conversation
| ```java | ||
| // Using binary search to find the minimum cap that we can ship the packages | ||
| // Min(left) will be the max value in the array, Max(right) will be sum of the values(when we need to ship everything in a day) | ||
| // During the search, if we can ship it meaning the smallest cap in left ~ mid |
There was a problem hiding this comment.
これでよいと思いますが、二分探索はいくつか書き方があるので、レビューワーの方が、リンクを探し出してまとめてくれることを期待します。
There was a problem hiding this comment.
-
https://discord.com/channels/1084280443945353267/1252267683731345438/1253724345369624596
二分探索は数種類あって、値を探すもの、境界を探すもの、あとは、閉区間か閉開区間かなどです。
-
Find Minimum in Rotated Sorted Array Exzrgs/LeetCode#11 (comment)
↑これとかまとまってるかなと思います -
https://discord.com/channels/1084280443945353267/1192736784354918470/1235596462084067369
-
300. Longest Increasing Subsequence YukiMichishita/LeetCode#7 (comment)
二分探索は、コードのパターンで覚えて書くのではなく、探索範囲が閉区間・半開区間・開区間のどれなのかを意識し、範囲を狭めるときに、範囲の端をどこまで狭めればよいかを意識して書くとよい
| return l; | ||
| } | ||
|
|
||
| public boolean canShip(int[] weights, int cap, int days) { |
| if (canShip(weights, mid, days)) { | ||
| r = mid; | ||
| } else { | ||
| l = mid + 1; | ||
| } |
There was a problem hiding this comment.
個人的に、こちらの方が Step3 よりも二分探索だ~と分かりやすかったです。
| // Time spend: 02:21 | ||
| class Solution { | ||
| public int shipWithinDays(int[] weights, int days) { | ||
| int l = -1; |
| ```java | ||
| // Using binary search to find the minimum cap that we can ship the packages | ||
| // Min(left) will be the max value in the array, Max(right) will be sum of the values(when we need to ship everything in a day) | ||
| // During the search, if we can ship it meaning the smallest cap in left ~ mid |
There was a problem hiding this comment.
-
https://discord.com/channels/1084280443945353267/1252267683731345438/1253724345369624596
二分探索は数種類あって、値を探すもの、境界を探すもの、あとは、閉区間か閉開区間かなどです。
-
Find Minimum in Rotated Sorted Array Exzrgs/LeetCode#11 (comment)
↑これとかまとまってるかなと思います -
https://discord.com/channels/1084280443945353267/1192736784354918470/1235596462084067369
-
300. Longest Increasing Subsequence YukiMichishita/LeetCode#7 (comment)
二分探索は、コードのパターンで覚えて書くのではなく、探索範囲が閉区間・半開区間・開区間のどれなのかを意識し、範囲を狭めるときに、範囲の端をどこまで狭めればよいかを意識して書くとよい
| if (daysNeed > days) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
関数末尾でreturn daysNeed <= daysとするほうが条件分岐が少なくて読みやすいと思いました
早期returnで余計なloopを回さないという意図はあると思うですが、僅かな差だと思うので可読性があがるほうが良いかなと
| } | ||
|
|
||
| while (l < r) { | ||
| int mid = (l + r) / 2; |
There was a problem hiding this comment.
この問題の場合は問題とならないと思うのですが、 l + r が int の範囲を超えてオーバーフローするのを防ぐため、 int mid = l + (r - l) / 2; と書いておいたほうが良いと思います。
https://ja.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%8E%A2%E7%B4%A2#%E5%AE%9F%E8%A3%85%E4%B8%8A%E3%81%AE%E9%96%93%E9%81%95%E3%81%84
よくある間違いの一つは、上記のC言語のコードで imin + (imax - imin) / 2 を (imax + imin) / 2 としてしまう事である。(imax + imin) / 2 では、imax + imin が int の値の上限 (INT_MAX) を超えて不正な値になってしまう可能性がある。(imax + imin が INT_MAX を超える可能性が全くないと保証できる場合は問題ない。)
|
|
||
| public boolean canShip(int[] weights, int cap, int days) { | ||
| int daysNeed = 1; | ||
| int currWeight = 0; |
There was a problem hiding this comment.
変数名に単語の省略形を使用すると、読むにあたり認知負荷が高くなるように思います。チーム内で合意形成が得られているもの以外については、フルスペルで書くことをお勧めいたします。
|
|
||
| while (l < r) { | ||
| int mid = (l + r) / 2; | ||
| if (canShip(weights, mid, days)) { |
There was a problem hiding this comment.
@goto-untrapped さんも指摘されている点ですが、 l と r の対称性を示すため、 continue せず if else としたほうが良いと思います。
https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/description/