es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cuál es la complejidad temporal de realizar dos búsquedas binarias en un arreglo ordenado que ha sido desplazado hacia la derecha en cierta cantidad?

Se me da un array ordenado que ha sido desplazado hacia la derecha en alguna cantidad.

Por ejemplo [45,61,71,72,73,0,1,21,33,37]; que es [0,1,21,33,37,45,61,71,72,73] desplazado hacia la derecha por 5 espacios.

También se nos da un entero objetivo que puede o no estar en el array. Si está en el array, se nos pide que devolvamos su índice, de lo contrario -1.

Mi solución utiliza iteración para encontrar el punto de quiebre del array ordenado, es decir, el punto donde deja de estar ordenado; en el ejemplo anterior esto está en el índice 4.

Luego, aplico dos búsquedas binarias: una para la primera mitad del array hasta el punto de quiebre, y otra desde el punto de quiebre hasta el final del array.

Mi pregunta es, ¿la complejidad temporal de esto sería O(log(n)), donde n es el número de enteros en el array? Mi entendimiento es que, dado que estamos utilizando dos búsquedas binarias, esto tomará un total de O(2 x log(n)) = O(log(n)).

Para completar, he incluido mi código modificado a continuación. Para describirlo simplemente, en cada ‘iteración‘, simplemente encontré la mitad del array que NO contiene el punto de quiebre y hice una simple comprobación (comparando el objetivo con los límites) sobre si el objetivo se encuentra en esta mitad; dado que esta mitad está totalmente ordenada, esto es una operación O(1). Por favor, avíseme si esto NO logra una complejidad temporal de O(log(n)) – ¡creo que ahora sí!

def shiftedBinarySearch(array, target):
    start = 0
    end = len(array) - 1

    while start < end:
        middle = (start + end) // 2

        if array[middle] == target:
            return middle

        else:
            #el punto de quiebre está en la segunda mitad de la lista
            if array[start] < array[middle]:
                if target >= array[start] and target < array[middle]:
                    end = middle
                else:
                    start = middle + 1
            #el punto de quiebre está en la primera mitad de la lista
            else:
                if target > array[middle] and target <= array[end]:
                    start = middle + 1

                else:
                    end = middle

    if start == end:
        if array[start] == target:
            return start

    return -1
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, tu solución logra una complejidad de tiempo de O(log(n)). Dado que estás realizando dos búsquedas binarias, cada búsqueda tiene una complejidad de tiempo de O(log(n)), lo que resulta en una complejidad de tiempo total de O(2 x log(n)) = O(log(n)).

    Tu código modificado parece correcto y sigue el enfoque que describiste. En cada iteración, divides el arreglo en dos mitades y reduces el espacio de búsqueda donde podría encontrarse el objetivo.

    En general, tu solución es eficiente y debería funcionar bien para tamaños de entrada grandes.

Comments are closed.