Conversation
|
|
||
| class Solution: | ||
| def findMin(self, nums: List[int]) -> int: | ||
| if nums == sorted(nums): |
There was a problem hiding this comment.
ここで O(n log n) かかってしまっていると思います。全体を通して O(log n) とするため、ここの処理を省けませんか?
|
|
||
| left = 0 | ||
| right = len(nums) - 1 | ||
| while right - left > 1: |
There was a problem hiding this comment.
自分は二分探索の問題が苦手なのですが…、第一感、この問題の、二分探索の問題としての捉え方が気になりました。この問題を、二分探索の問題としてと洗えた時、どのような問題に落とし込んでいますか?
- False と True が一列に並んでおり、あるところまでは False で、あるところから True のとき、 False と True の境界を求める問題。
- False と True が一列に並んでおり、あるところまでは False で、あるところから True のとき、最初の True を見つける問題。
There was a problem hiding this comment.
前者ですね。境界を求めたくて、leftとrightで境界を挟むように狭めたいと思いました。
There was a problem hiding this comment.
ありがとうございます。続いて、区間は開区間・閉区間・半開区間のどれを想定していますか?
There was a problem hiding this comment.
こちら、自分が用語として正しく認識できているか自信がないのですが、left, rightの初期値のことと考えて問題ないでしょうか?
境界を挟もうと思うとleft, rightの両方が範囲に収まる必要があるので、閉区間、ですかね...?
There was a problem hiding this comment.
ありがとうございます。 left・right の初期値というより、 left と right の間の区間を考えるときに、区間に left 自体を含めるかどうか、 right 自体を含めるかどうかだと思います。
開区間・閉区間・半開区間について、詳しくは以下のページをご覧ください。
- https://w3e.kanazawa-it.ac.jp/math/category/other/syuugou/henkan-tex.cgi?target=/math/category/other/syuugou/kukann.html
- http://www.mu.c.titech.ac.jp/Dmath/intervals.html
閉区間を想定している点は合っていると思います。
閉区間を想定する場合、nums[left] <= nums[mid] の場合、mid の位置の要素は、区間を狭めたあと、区間の外に追い出したいですよね。なぜならば、 mid の位置の要素は、 nums[0] から昇順に並んでいる値のうちの一つだからです。本来探したい要素はもっと右にあるので、 left = mid ではなく、 left = mid + 1 と、 mid の右を新しい left とするのが良いと思います。
逆に nums[left] > nums[mid] の場合、 mid の位置の要素は、区間を狭めたあと、区間の中に入っていないとまずいです。なぜならば、 mid の位置の要素は、 num[0] から値が昇順に並んだあと、一度小さくなったあとの要素の一つであり、一番小さい値かもしれないためです。よって right = mid とすることになると思います。
また、終了条件は要素が 1 つに絞られたときだと思います。これは閉区間で考えると、 left == right の場合だと思います。よって while の条件は left < right とするのが良いと思います。
上記の考え方に基づいて、もう一度コードを書いてみていただけますか?
上記の説明で怪しい部分があれば、指摘をお願いします。 > 講師役の皆様
There was a problem hiding this comment.
なるほど...
自分のイメージとは前提が違っているかもしれないです?
自分は、
[4,5,6,7,0,1,2]
のとき、
leftを7に、rightを0に持っていきたいと思ってコードを書いていました。
There was a problem hiding this comment.
FalseとTrueでいうと、leftをFalseに、rightをTrueにしたかったですね
There was a problem hiding this comment.
そうすると、閉区間ではなく、開区間で考えているように思います。また、初期値は left = -1、 right = len(nums) としなければまずいように思います。ただし、すべてが False になるケースは考えなくてよいため、この問題の場合は例外的に right = len(nums) - 1 としても問題ないかもしれません。
#11 (comment)
の考え方に従って書き直してみていただけますか?
There was a problem hiding this comment.
問題:https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/description
参考:
https://github.com/hayashi-ay/leetcode/pull/45/files
https://github.com/YukiMichishita/LeetCode/pull/9/files