Search rotated permutation array
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.
-
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
-
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 1≤nums.length≤5000
- − 1 0 4 ≤ n u m s [ i ] ≤ 1 0 4 -10^4 \leq nums[i] \leq 10^4 −104≤nums[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 −104≤target≤104
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)