Búsqueda de matriz de permutación rotada
1. Descripción del tema:
Los números de la matriz de enteros se organizan en orden ascendente, y los valores de la matriz son diferentes entre sí.
Antes de pasar a la función, nums se rota en un subíndice k previamente desconocido (0 <= k < nums.length), de modo que la matriz se convierte en [nums[k], nums[k+1], …, nums[ n-1], nums[0], nums[1], …, nums[k-1]] (los subíndices empiezan a contar desde 0). Por ejemplo, [0,1,2,4,5,6,7] podría convertirse en [4,5,6,7,0,1,2] después de la rotación en el índice 3.
Déle los números de la matriz rotada y un objetivo entero, si el objetivo del valor objetivo existe en números, devuelva su subíndice; de lo contrario, devuelva -1.
Tienes que diseñar un algoritmo con complejidad de tiempo O(log n) para resolver este problema.
-
Ejemplo 1:
- Entrada: números = [4,5,6,7,0,1,2], objetivo = 0
- Salida: 4
-
Ejemplo 2:
- Entrada: números = [4,5,6,7,0,1,2], objetivo = 3
- Salida: -1
-
Ejemplo 3:
- Entrada: números = [1], objetivo = 0
- Salida: -1
- pista:
- 1 ≤ números . longitud ≤ 5000 1 \leq nums.longitud \leq 50001≤números _ _ _ _ longitud _ _ _ _ _≤5000
- − 1 0 4 ≤ números [ yo ] ≤ 1 0 4 -10^4 \leq números[i] \leq 10^4− 1 04≤números [ yo ] _ _ _≤1 04
- Cada valor en nums es único
- − 1 0 4 ≤ objetivo ≤ 1 0 4 -10^4 \leq objetivo \leq 10^4− 1 04≤objetivo _ _ _ _ _≤1 04
2. Soluciones y códigos
1. Soluciones
- Análisis: Resolver en dos pasos: segmentación, búsqueda, ambos pasos utilizan el método de búsqueda binaria
- Dividir: divide la matriz rotada en dos matrices crecientes [Índice de búsqueda binaria]
- Buscar: compare el tamaño de los dos valores de target y nums[0], y determine en qué matriz incremental buscar [Valor objetivo de búsqueda binaria]
2. Código
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)