Leetcode33. Searching arrays with rotation permutations

1. Description of the topic:

The integer array nums is arranged in ascending order, and the values ​​in the array are different from each other.

Before being passed to the function, nums is rotated on a pre-unknown subscript k (0 <= k < nums.length), so that the array becomes [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]] (subscripts start counting from 0). For example, [0,1,2,4,5,6,7] could become [4,5,6,7,0,1,2] after rotation at index 3.

Give you the rotated array nums and an integer target, if the target value target exists in nums, return its subscript, otherwise return -1.

You have to design an algorithm with O(log n) time complexity to solve this problem.

  1. Example 1:

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

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

    • Input: nums = [1], target = 0
    • Output: -1
  • hint:
    • 1 ≤ n u m s . l e n g t h ≤ 5000 1 \leq nums.length \leq 5000 1nums.length5000
    • − 1 0 4 ≤ n u m s [ i ] ≤ 1 0 4 -10^4 \leq nums[i] \leq 10^4 104nums[i]104
    • Each value in nums is unique
    • − 1 0 4 ≤ t a r g e t ≤ 1 0 4 -10^4 \leq target \leq 10^4 104target104

2. Solutions and codes

1. Solutions

  • Analysis: Solve in two steps: segmentation, search, both steps use the method of binary search
    • Split: Divide the rotated array into two increasing arrays [Binary Search Index]
    • Search: compare the size of the two values ​​of target and nums[0], and determine which incremental array to search in [Binary search target value]

2. Code

from typing import *
class Solution:
    def getIndex(self, nums:List[int]) -> int:
        left, right = 0, len(nums)-1
        while left<=right:
            mid = (left+right)//2
            if nums[mid]>nums[left] and nums[mid]>nums[right]:
                left = mid
            elif nums[mid]<nums[left] and nums[mid]<nums[right]:
                right = mid
            else:
                return left if nums[left]<nums[right] else right
        return -1
    
    def binarySearch(self,nums:List[int], target:int, start:int, end:int) -> int:
        while start<=end:
            mid = (start+end)//2
            if nums[mid]<target:
                start = mid+1
            elif nums[mid]>target:
                end = mid-1
            else:
                return mid
        return -1
    
    def search(self, nums: List[int], target: int) -> int:
        start = self.getIndex(nums)
        if start == -1 or start==0:
            return self.binarySearch(nums,target,0,len(nums)-1)
        if target>=nums[0]:
            return self.binarySearch(nums,target,0,start-1)
        else:
            return self.binarySearch(nums,target,start,len(nums)-1)

Guess you like

Origin blog.csdn.net/qq_40541102/article/details/130156023