[Diario de algoritmo superado] día 10 —— 704. Búsqueda binaria, 34. Encuentre la primera y última posición de un elemento en una matriz ordenada

 

 704. Búsqueda binaria 

704. Búsqueda binaria

Tema Descripción: 

Dada una  n matriz entera ordenada (ascendente) de elementos  nums y un valor objetivo  target  , escriba una función que  nums devuelva  targetel índice si el valor objetivo existe; de ​​lo contrario, devuelva  -1

Ideas para resolver problemas: 

La matriz en esta pregunta está ordenada y bisegmentada, por lo que podemos usar el algoritmo binario para resolver este problema.

Vale la pena señalar que cuando la izquierda y la derecha continúan moviéndose hacia el centro, la izquierda y la derecha pueden apuntar a la misma posición, y esta posición debe juzgarse, por lo que nuestra condición de bucle es izquierda <= derecha

 Código de solución:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0;
        int right=nums.size()-1;
        while(left<=right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]==target) return mid;
            if(nums[mid]>target) right=mid-1;
            if(nums[mid]<target) left=mid+1;
        }
        return -1;
        }
};

 34. Encuentre la primera y última posición del elemento en una matriz ordenada

34. Encuentre la primera y última posición del elemento en una matriz ordenada

 Tema Descripción:

Se le proporciona una matriz de números enteros en orden no decreciente  numsy un valor objetivo  target. Encuentre la posición inicial y la posición final del valor objetivo dado en la matriz.

targetDevuelve  si el valor objetivo no existe en la matriz  [-1, -1].

O(log n) Debe diseñar e implementar un algoritmo con una complejidad temporal de  .

Ideas para resolver problemas:

En esta pregunta usamos la bisección para resolver el problema de los extremos izquierdo y derecho. En primer lugar, debe haber izquierda y derecha.

Entendamos esta pregunta a través de un ejemplo: [1,2,3,3,3,4,5]

Encuentre el punto final izquierdo : aquí usamos t en lugar de objetivo (esto es más fácil de describir)

  • Operación de pensamiento binario: podemos dividir el ejemplo anterior en dos partes, porque ahora estamos buscando el punto final izquierdo, por lo que puedo dividir el ejemplo en [[1,2], [ 3,3,3,4,5 ] ]

  1. Cuando x<t, está en el intervalo [1,2], izquierda=mid+1
  2. Cuando x>=t, está en el intervalo [3,3,3,4,5], derecha=mid (aquí no puede ser igual a mid-1, porque si mid=0, right=-1 saldrá de límites)
  • Detalles:

Condición del bucle:

  1. izquierda<derecha     
  2. izquierda<=derecha    ×

¿Cuál elegimos? Vamos a discutir:

  1. hay resultados
  2. Todos son mayores que t (t1), la derecha sigue hacia la izquierda y finalmente la derecha termina con la izquierda. Si izquierda <= derecha, habrá un bucle infinito.
  3. Todos son menores que t (t2), la izquierda continúa hacia la derecha y finalmente la izquierda termina a la derecha de la derecha.

¡De esto solo podemos elegir la primera opción pero no la segunda!

Encuentre la operación intermedia:

  1. izquierda+(derecha-izquierda)/2         ×
  2. izquierda+(derecha-izquierda+1)/2    

¡Descubrámoslo considerando los casos extremos! Cuando solo quedan dos elementos:

No hay problema con el primer tipo, pero con el segundo tipo mid = 0 + 2/2 = 1. Cuando se realiza la operación izquierda + 1, ocurrirá un evento fuera de límites.

Encuentre el punto final correcto :

  • Operación de pensamiento binario: podemos dividir el ejemplo anterior en dos partes, porque ahora estamos buscando el punto final izquierdo, por lo que puedo dividir el ejemplo en [[1,2,3,3,3].[ 4,5 ] ]

  1. Cuando x<=t, está en el intervalo [1,2,3,3,3], izquierda=media
  2. Cuando x>t, está en el intervalo [4,5], derecha = mitad-1
  • Detalles:

Condición del bucle:

  1. izquierda<derecha     
  2. izquierda<=derecha    ×

O elige izquierda <derecha

Encuentre la operación intermedia:

  1. izquierda+(derecha-izquierda)/2        
  2. izquierda+(derecha-izquierda+1)/2     ×

¡Descubrámoslo considerando los casos extremos! Cuando solo quedan dos elementos:

En el primer caso, cuando mid=0+1/2=0, right=mid-1 está fuera de límites. En el segundo caso, no hay problema.

Código de solución:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        //特殊情况处理一下
        if(nums.size()==0)return {-1,-1};
        int left=0,right=nums.size()-1;
        vector<int> ret;
        //查找左端点
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]<target)left=mid+1;
            if(nums[mid]>=target)right=mid;
        }
        //当left==right时就是结果
        if(nums[left]!=target)return {-1,-1};
        else ret.push_back(left);
        //查找右端点
        left=0,right=nums.size()-1;
        while(left<right)
        {
            int mid=left+(right-left+1)/2;
            if(nums[mid]<=target)left=mid;
            if(nums[mid]>target)right=mid-1;
        }
        if(nums[right]!=target)return {-1,-1};
        else ret.push_back(right);
        return ret;
    }
};

 

Supongo que te gusta

Origin blog.csdn.net/m0_69061857/article/details/133323980
Recomendado
Clasificación