-
Notifications
You must be signed in to change notification settings - Fork 0
33. Search in Rotated Sorted Array #29
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
base: main
Are you sure you want to change the base?
Conversation
| def cmp(a, b): | ||
| return (a > b) - (a < b) | ||
| def priority(x): | ||
| return (nums[-1] < x) * -2 + cmp(x, target) |
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.
これ、単に (x <= nums[-1], x) でいけます。
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.
補足すると、タプルの1個目の判定で[False, ..., False, True, ..., True]というような単調述語で先に順序づけされます。(pythonのFalse, Trueはintに型変換すると0, 1になるので広義単調増加。)
あと、下記のように2回bisect_leftを使う書き方もあります。key=lambda x: (x <= nums[-1], x)でまとめず分割してやっていることに相当します。
import bisect
class Solution:
def search(self, nums: list[int], target: int) -> int:
min_index = bisect.bisect_left(nums, True, key=lambda x: x <= nums[-1])
if target <= nums[-1]:
lo, hi = min_index, len(nums)
else:
lo, hi = 0, min_index
target_index = bisect.bisect_left(nums, target, lo=lo, hi=hi)
if target_index < hi and nums[target_index] == target:
return target_index
return -1| def cmp(a, b): | ||
| return (a > b) - (a < b) | ||
| def priority(x): | ||
| return (nums[-1] < x) * -2 + cmp(x, target) |
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.
補足すると、タプルの1個目の判定で[False, ..., False, True, ..., True]というような単調述語で先に順序づけされます。(pythonのFalse, Trueはintに型変換すると0, 1になるので広義単調増加。)
あと、下記のように2回bisect_leftを使う書き方もあります。key=lambda x: (x <= nums[-1], x)でまとめず分割してやっていることに相当します。
import bisect
class Solution:
def search(self, nums: list[int], target: int) -> int:
min_index = bisect.bisect_left(nums, True, key=lambda x: x <= nums[-1])
if target <= nums[-1]:
lo, hi = min_index, len(nums)
else:
lo, hi = 0, min_index
target_index = bisect.bisect_left(nums, target, lo=lo, hi=hi)
if target_index < hi and nums[target_index] == target:
return target_index
return -1| right = mid - 1 | ||
|
|
||
| return -1 | ||
| ``` |
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.
自分なら下記のように書きます。
class Solution:
def search(self, nums: List[int], target: int) -> int:
"""
不変条件:
- leftより左はrotationエリアが違うか、targetより小さい
- rightより右はrotationエリアが違うか、target以上
区間 left <= x <= right のサイズが0になるまで探索する。
"""
left = 0
right = len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] > nums[-1] and target <= nums[-1]:
left = mid + 1
continue
if nums[mid] <= nums[-1] and target > nums[-1]:
right = mid - 1
continue
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
# right + 1 = left の状況。
# 不変条件より、targetと等しくなりうるのはnums[left]のみ。
if left < len(nums) and nums[left] == target:
return left
return -1
33. Search in Rotated Sorted Array
次回予告: 39. Combination Sum