Skip to content

Conversation

@skypenguins
Copy link
Owner

33. Search in Rotated Sorted Array

次回予告: 39. Combination Sum

@skypenguins skypenguins self-assigned this Nov 24, 2025
def cmp(a, b):
return (a > b) - (a < b)
def priority(x):
return (nums[-1] < x) * -2 + cmp(x, target)
Copy link

Choose a reason for hiding this comment

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

これ、単に (x <= nums[-1], x) でいけます。

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)

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
```

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants