Directorio de artículos
Prefacio
Supongamos que hay una tubería de 1000 metros de largo y hay un agujero en un lugar desconocido, si queremos encontrar este agujero, ¿cómo debemos buscarlo?
En nuestra aplicación real, puede ver la secuencia de descarga secuencial en muchos lugares, como la descarga en orden de precio creciente, la descarga secuencial según el tamaño del objeto y problemas como la inspección de la tubería anterior, etc.
Si necesita encontrar un cierto valor que cumpla con las condiciones, costará una gran cantidad de búsquedas innecesarias para buscar en orden. En este momento, usar dos puntos puede ahorrar mucho costo.
Frente a la tubería de 1000 metros anterior, podemos adoptar un mecanismo de dicotomía, y cada vez excluimos tantas tuberías como sea posible para la próxima búsqueda.
Búsqueda binaria
Para comprender mejor el proceso de búsqueda de plantillas, primero demos un ejemplo simple
En una lista ordenada, busque el elemento 54
primera ronda
l = 0
r = 13
mid = (l + r) / 2 = 6
En este momento, el número señalado por mid es menor que 54, por lo que 54 está entre mid y r, y se pueden excluir todos los datos de 1 a mid.
Segunda ronda
l = mid + 1 = 7
r = 13(不变)
mid = (l + r) / 2 = 10
En este momento, el número señalado por mid es mayor que 54, por lo que 54 está entre ly mid, y se pueden excluir todos los datos de mid ar.
Tercera ronda
l = 7(不变)
r = mid = 10
mid = (l + r) / 2 = 8
En este momento, el número señalado a mediados es 54 y la búsqueda finaliza.
Complejidad de tiempo: O (logN)
Complejidad espacial: O (1)
La complejidad aquí es en realidad la complejidad promedio. La complejidad de tiempo de nivel logarítmico en el algoritmo utiliza la idea de dividir y conquistar. Esta base está determinada por la complejidad de dividir y conquistar, es decir, se utiliza el mecanismo de búsqueda binaria. Entonces su base es 2.
Plantilla 1
Refiérase a la plantilla de cierto jefe, hice algunas explicaciones para facilitar el aprendizaje
Cuando el intervalo [l, r]
se divide en [l, mid]
, y [mid + 1, r]
durante sus operaciones de actualización son r = mid
o l = mid + 1
;, no es necesario agregar 1 mid calculado.
Plantilla de código
function search_1(l, r)
{
while (l < r)
{
var mid = l + r >> 1;
if(/*mid找到*/) return mid;
if (check(mid)) r = mid;
else l = mid + 1;
}
return false;
}
-
¿Por qué es
l < r
una condición para ponerle fin?Respuesta: De acuerdo con la imagen de arriba, si no se ha encontrado el objetivo, los punteros izquierdo y derecho se superpondrán y, una vez que se superpongan, saldrán.
-
¿Por qué usarlo
l + r >> 1
, hay otras formas?Solución: En JavaScript, por
parseInt()
yMath.floor()
el método de tomar un número entero decimal, y>>
es de manera desplazable empleada, parece que una flecha a la derecha indica uno, es decir, dividida por 2 y luego redondeada, y esta vezMath.floor((l + r) / 2)
El efecto es el mismo.
Plantilla 2
Cuando el intervalo [l, r]
se divide en [l, mid - 1]
, y [mid, r]
durante su actualización, las operaciones son r = mid - 1
o l = mid
; en este momento para evitar un bucle infinito, la computación mid
debe agregar 1.
function search_2(l, r)
{
while (l < r)
{
var mid = l + r + 1 >> 1;
if(/*mid找到*/) return mid;
if (check(mid)) l = mid;
else r = mid - 1;
}
return false;
}
usar
Aún la matriz anterior, use la plantilla 1 para encontrar 54
var array = [1, 2, 4, 9, 11, 15, 20, 25, 54, 90, 100, 110, 111, 242];
function search_1(nums, target) {
if (target == null || nums.length == 0) return false;
var l = 0,
r = nums.length - 1;
while (l < r) {
var mid = (l + r) >> 1;
if(target == nums[mid]) return mid;
if (target < nums[mid]) {
r = mid;
} else {
l = mid + 1;
}
}
return false;
}
function search_2(nums, target) {
if (target == null || nums.length == 0) return false;
var l = 0,
r = nums.length - 1;
while (l < r) {
var mid = (l + r + 1) >> 1;
if(target == nums[mid]) return mid;
if(target > nums[mid]) l = mid;
else r = mid - 1;
}
return false;
}
para resumir
La búsqueda binaria requiere que los datos estén en orden.
- La posición media se compara con el objetivo y se encuentra si es igual. De lo contrario, divida la tabla original en dos tablas
- Cuando
l > r
no se encuentra el tiempo.