LeetCode Brushing Notes 01 Two Sum

Autor: Ma Zhifeng
Enlace: https: //zhuanlan.zhihu.com/p/23610451
Fuente: saber casi con
derechos de autor del autor. Para reimpresiones comerciales, comuníquese con el autor para obtener autorización. Para reimpresiones no comerciales, indique la fuente.

¿Qué le parece, después de estudiar los primeros 3 capítulos, no ha podido contenerse? ¿No estás satisfecho con hacer ejercicios después de la escuela?

Sucede que hoy es fin de semana, tenemos mucho tiempo, cepillemos un código de lectura

enlace

Two Sum | LeetCode OJ

tema

Dada una matriz de enteros y otro entero, encuentre dos enteros en la matriz para que su suma sea igual al entero dado. Devuelve los subíndices de estos dos enteros.
Suponiendo que siempre se pueden encontrar dos de estos números, y el resultado es único

Ejemplo

Dado nums = [2, 7, 11, 15], objetivo = 9,
porque nums [0] + nums [1] = 2 + 7 = 9,
devuelve [0, 1].

Después de comprender el significado del problema, comenzamos oficialmente a resolverlo.

Te sugiero que lo pruebes tú mismo primero.

primera ronda

Quizás la forma más fácil de pensar es resolver este problema a través de dos bucles

El bucle exterior atraviesa desde 0: [02, 07, 11]

El bucle interno comienza en 1: [07, 11, 15]

Si la suma de los enteros en la posición correspondiente es igual al valor dado, se devuelve el subíndice

Arrastramos la página hacia abajo, seleccionamos "c ++" en el cuadro desplegable y ya puede empezar a codificar.

Se recomienda que primero escriba y lea y piense en varias formas de resolver el problema.

Después de pensarlo, puede codificar directamente en el sitio web sin la ayuda de un IDE.

Lo escribí así:

class Solution {  
public:  
    vector<int> twoSum(vector<int>& nums, int target) {  
        vector<int> vecResult;  

        for( int i = 0; i < nums.size() - 1; ++i )  
        {  
            for( int j = i + 1; j < nums.size(); ++j )  
            {  
                if( nums[i] + nums[j] == target )  
                {  
                    vecResult.push_back( i );  
                    vecResult.push_back( j );  
                    return vecResult;  
                }  
            }  
        }  

        return vecResult;  
    }  
};

Haga clic en "Ejecutar código" , oh sí, ¡una pasada!
Haga clic en "Enviar solución" , OK, ¡aceptado!
Haga clic en "Detalle" para echar un vistazo, Dios mío, qué demonios. ¡Tomó 809ms! ¡Vence al 5,6% de los usuarios!
¡Es tan jodido como la velocidad de arranque del recordatorio 360 supera al 1% de los usuarios del país! ! !

Estudie cuidadosamente:
nums.size () ha sido llamado demasiadas veces. ¿Qué pasa si lo llama una vez para guardar el resultado?
OKAY,

Segunda ronda

Haga clic en "Editar código" para modificar el código.

class Solution {
      
        
public:  
    vector<int> twoSum(vector<int>& nums, int target) {
      
        
        vector<int> vecResult;  

        auto iSize = nums.size();  
        for( int i = 0; i < iSize - 1; ++i )  
        {
      
        
            for( int j = i + 1; j < iSize; ++j )  
            {
      
        
                if( nums[i] + nums[j] == target )  
                {
      
        
                    vecResult.push_back( i );  
                    vecResult.push_back( j );  
                    return vecResult;  
                }  
            }  
        }  

        return vecResult;  
    }  
};

Veamos los detalles después del envío, lo borré, ¡486 ms! ¡Derrota al 33,49% de los usuarios! ! !
Se ha incrementado en más de 20 puntos porcentuales. Compruebe que el número total de presentaciones aceptadas es 273.183. Esto multiplicado por más de 50.000. La confianza en uno mismo se ha disparado, ¡no hay nada! ! !

Mirándolo de nuevo, iSize-1 ha sido llamado muchas veces, el mismo problema. De acuerdo, guárdalo con anticipación y pruébalo.

class Solution {
      
        
public:  
    vector<int> twoSum(vector<int>& nums, int target) {
      
        
        vector<int> vecResult;  

        auto iSize = nums.size();  
        auto iOutterSize = iSize - 1;  
        for( int i = 0; i < iOutterSize; ++i )  
        {
      
        
            for( int j = i + 1; j < iSize; ++j )  
            {
      
        
                if( nums[i] + nums[j] == target )  
                {
      
        
                    vecResult.push_back( i );  
                    vecResult.push_back( j );  
                    return vecResult;  
                }  
            }  
        }  

        return vecResult;  
    }  
};

¡Someta, mierda, 496ms! ¿Por qué lleva más tiempo? ¿Es posible definir una cantidad temporal para que afecte los resultados de rendimiento?

¿Qué diablos está pasando? ¿Pueden decirme todos los grandes dioses?

Después de pensarlo durante mucho tiempo, no lo pensé, así que primero escribí el problema. Continuemos.

El libro dice que la matriz se puede inicializar mediante la inicialización de la lista. Cambiemos el valor de retorno para ver si se puede mejorar.

Okay

Tercera ronda

class Solution {  
public:  
    vector<int> twoSum(vector<int>& nums, int target) {  

        auto iSize = nums.size();  
        for( int i = 0; i < iSize - 1; ++i )  
        {  
            for( int j = i + 1; j < iSize; ++j )  
            {  
                if( nums[i] + nums[j] == target )  
                {  
                    return { i, j };  
                }  
            }  
        }  

        vector<int> vecResult;  
        return vecResult;  
    }  
};

499ms? ¿Está bien esta estadística?

Pero el libro también dice que se recomienda crear un vector vacío y luego agregar elementos dinámicamente. Parece que la eficiencia de la adición dinámica es de hecho mayor

Cambiamos return {i, j} para crear un valor temporal e intentamos regresar

vector<int> temp = { i, j };  
return temp;

652ms, realmente lleva tiempo crear una cantidad temporal

Por supuesto, estas son nuestras explicaciones superficiales. Antes de profundizar en el conocimiento, también podríamos escribirlas y guardarlas para futuras exploraciones.

Piense en qué más se puede cambiar. ? ?

Hay tres formas de acceder a los elementos de la secuencia.

  • Rango para
  • Subíndice
  • Iterador

Solo usamos subíndices. El rango de no es fácil de usar. ¿Por qué no probamos primero los iteradores?

Cuarta ronda

class Solution {
      
        
public:  
    vector<int> twoSum(vector<int>& nums, int target) {
      
        
        vector<int> vecResult;  
        int i = 0;  
        for( auto itr = nums.begin(); itr != nums.end() - 1; ++itr)  
        {
      
        
            int j = i + 1;  
            for( auto itrInner = itr + 1; itrInner != nums.end(); ++itrInner )  
            {
      
        
                if( (*itr) + (*itrInner) == target )  
                {
      
        
                    vecResult.push_back( i );  
                    vecResult.push_back( j );  
                    return vecResult;  
                }  
                ++j;  
            }  
            ++i;  
        }  

        return vecResult;  

    }  
};

Al escribir código, debemos saber que los iteradores no son adecuados para este tipo de búsqueda de subíndices.

Tenemos que definir dos variables i y j para registrar el subíndice

El hecho es exactamente el mismo: cuando enviamos el código, nos rechazaron porque tomó demasiado tiempo frente a un gran conjunto de datos.

Bueno, hasta ahora parece que solo tendremos tanto.

¿Es realmente? ¿Hay alguna otra forma que no esperaba? ¿Echar un vistazo más de cerca a las notas?

¿Alguna vez ha intentado modificar los parámetros de entrada?

vector<int> twoSum(const vector<int> &nums, const int &target)

¿Existe una solución que se pueda resolver sin dos bucles?

Si realmente no puede resolverlo, puede ir al área de discusión para ver las soluciones de otras personas

Dos Sumas




Supongo que te gusta

Origin blog.csdn.net/qq_26751117/article/details/53156022
Recomendado
Clasificación