回転順列配列の検索
1. トピックの説明:
整数配列 nums は昇順に並べられており、配列内の値はそれぞれ異なります。
関数に渡される前に、nums は未知の添字 k (0 <= k < nums.length) に基づいて回転され、配列は [nums[k], nums[k+1], …, nums[ n-1]、nums[0]、nums[1]、…、nums[k-1]] (添え字は 0 から数え始めます)。たとえば、[0,1,2,4,5,6,7] は、インデックス 3 で回転すると [4,5,6,7,0,1,2] になる可能性があります。
回転された配列 nums と整数ターゲットを指定します。ターゲット値ターゲットが nums に存在する場合はその添え字を返し、それ以外の場合は -1 を返します。
この問題を解決するには、時間計算量が O(log n) のアルゴリズムを設計する必要があります。
-
例 1:
- 入力: 数値 = [4,5,6,7,0,1,2]、ターゲット = 0
- 出力: 4
-
例 2:
- 入力: 数値 = [4,5,6,7,0,1,2]、ターゲット = 3
- 出力: -1
-
例 3:
- 入力: 数値 = [1]、ターゲット = 0
- 出力: -1
- ヒント:
- 1 ≤ 数値。長さ ≤ 5000 1 \leq nums.length \leq 50001≤数値。_ _ _ 長さ_ _ _ _≤5000
- − 1 0 4 ≤ nums [ i ] ≤ 1 0 4 -10^4 \leq nums[i] \leq 10^4− 1 04≤数値[ i ] _ _ _≤1 04
- nums の各値は一意です
- − 1 0 4 ≤ ターゲット ≤ 1 0 4 -10^4 \leq ターゲット \leq 10^4− 1 04≤ターゲット_ _ _ _ _≤1 04
2. ソリューションとコード
1. 解決策
- 分析: 2 つのステップで解決します: セグメンテーション、検索、両方のステップで二分探索の方法が使用されます。
- 分割: 回転された配列を 2 つの増加する配列に分割します [二分探索インデックス]
- 検索:targetとnums[0]の2つの値の大小を比較し、[二分探索対象値]でどの増分配列を検索するかを決定します
2. コード
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)