代码改变世界

[LeetCode] 33. Search in Rotated Sorted Array_Medium tag: Binary Search

2019-04-16 10:26  Johnson_强生仔仔  阅读(189)  评论(0编辑  收藏  举报

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

Your algorithm's runtime complexity must be in the order of O(log n).

Example 1:

Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4

Example 2:

Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1

1) 这个题目思路就是先画图, 分区间讨论,注意是左移还是右移,最好画图判断下。

2)可以利用[LeetCode] 153. Find Minimum in Rotated Sorted Array_Medium tag: Binary Search 的思路,通过lg n 找到转折点,然后分别在两段里面找。

T: O(lgn)

Code

1)

class Solution:
    def search(self, nums, target):
        if not nums: return -1
        S, E, l, r = nums[0], nums[-1], 0, len(nums) - 1
        while l + 1 < r:
            mid = l + (r - l)//2
            if target == nums[mid]: return mid
            if nums[mid] >= S:
                if S <= target <= nums[mid]:
                    r = mid
                else:
                    l = mid
            else:
                if nums[mid] <= target <= E:
                    l = mid
                else:
                    r = mid
        if nums[l] == target: return l
        if nums[r] == target: return r
        return -1

 

2) Code

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        self.nums = nums
        self.target = target
        min_index = self.findMinIndex()
        return max(self.searchTarget(0, min_index - 1), self.searchTarget(min_index, len(nums) - 1))
    
    def searchTarget(self, l: int, r: int) -> int:
        if l > r or self.target < self.nums[l] or self.target > self.nums[r]:
            return -1
        while l + 1 < r:
            mid = l + (r - l)//2
            num = self.nums[mid]
            if num < self.target:
                l = mid
            elif num > self.target:
                r = mid
            else:
                return mid
        if self.nums[l] == self.target: return l
        if self.nums[r] == self.target: return r
        return -1
    

    def findMinIndex(self):
        l, r = 0, len(self.nums) - 1
        while l + 1 < r:
            mid = l + (r - l)//2
            num = self.nums[mid]
            if num <= self.nums[-1]:
                r = mid
            else:
                l = mid
        return l if self.nums[l] <= self.nums[-1] else r