-
Notifications
You must be signed in to change notification settings - Fork 0
Find Minimum in Rotated Sorted Array #11
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
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,19 @@ | ||
| """ | ||
| 5m30s | ||
| 前やったのとほぼ同じ | ||
| """ | ||
|
|
||
| class Solution: | ||
| def findMin(self, nums: List[int]) -> int: | ||
| if nums == sorted(nums): | ||
| return nums[0] | ||
|
|
||
| left = 0 | ||
| right = len(nums) - 1 | ||
| while right - left > 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. 自分は二分探索の問題が苦手なのですが…、第一感、この問題の、二分探索の問題としての捉え方が気になりました。この問題を、二分探索の問題としてと洗えた時、どのような問題に落とし込んでいますか?
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. 前者ですね。境界を求めたくて、leftと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. ありがとうございます。続いて、区間は開区間・閉区間・半開区間のどれを想定していますか?
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. こちら、自分が用語として正しく認識できているか自信がないのですが、left, 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. ありがとうございます。 left・right の初期値というより、 left と right の間の区間を考えるときに、区間に left 自体を含めるかどうか、 right 自体を含めるかどうかだと思います。 開区間・閉区間・半開区間について、詳しくは以下のページをご覧ください。
閉区間を想定している点は合っていると思います。 閉区間を想定する場合、 逆に また、終了条件は要素が 1 つに絞られたときだと思います。これは閉区間で考えると、 left == right の場合だと思います。よって while の条件は left < right とするのが良いと思います。 上記の考え方に基づいて、もう一度コードを書いてみていただけますか? 上記の説明で怪しい部分があれば、指摘をお願いします。 > 講師役の皆様
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. なるほど...
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. FalseとTrueでいうと、leftをFalseに、rightをTrueにしたかったですね 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. そうすると、閉区間ではなく、開区間で考えているように思います。また、初期値は left = -1、 right = len(nums) としなければまずいように思います。ただし、すべてが False になるケースは考えなくてよいため、この問題の場合は例外的に right = len(nums) - 1 としても問題ないかもしれません。 #11 (comment)
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. 見落としていました。よいと思います。 |
||
| mid = (left + right) // 2 | ||
| if nums[left] <= nums[mid]: | ||
| left = mid | ||
| else: | ||
| right = mid | ||
| return nums[right] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| """ | ||
| わざわざソートしなくても比較するだけでよい | ||
| """ | ||
|
|
||
| class Solution: | ||
| def findMin(self, nums: List[int]) -> int: | ||
| if nums[0] <= nums[-1]: | ||
| return nums[0] | ||
|
|
||
| left = 0 | ||
| right = len(nums) - 1 | ||
| while right - left > 1: | ||
| mid = (left + right) // 2 | ||
| if nums[left] <= nums[mid]: | ||
| left = mid | ||
| else: | ||
| right = mid | ||
| return nums[right] | ||
|
|
||
| # 固定値と比較して寄せていくパターン | ||
| # これならソートされていても動く | ||
| class Solution: | ||
| def findMin(self, nums: List[int]) -> int: | ||
| left = -1 | ||
| right = len(nums) - 1 | ||
| while right - left > 1: | ||
| mid = (left + right) // 2 | ||
| if nums[mid] >= nums[-1]: | ||
| left = mid | ||
| else: | ||
| right = mid | ||
| return nums[right] | ||
|
|
||
| # leftをmidより動かすパターン | ||
| # 最小値を直接あてに行く | ||
| class Solution: | ||
| def findMin(self, nums: List[int]) -> int: | ||
| left = 0 | ||
| right = len(nums) - 1 | ||
| while left < right: | ||
| mid = (left + right) // 2 | ||
| if nums[mid] <= nums[-1]: | ||
| right = mid | ||
| else: | ||
| left = mid + 1 | ||
| return nums[left] |
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.
ここで O(n log n) かかってしまっていると思います。全体を通して O(log n) とするため、ここの処理を省けませんか?
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.
step2で改良しています!