Conceptos básicos de la estructura de datos día 5

Tema: 334. Subsecuencia ternaria creciente

Mi solución: bucle de tres capas (tiempo de espera)

Otra solución 1: recorrido bidireccional

Encuentre el valor más pequeño a la izquierda y el valor más grande a la derecha de la posición i-ésima

class Solution {
    
    
public:
    bool increasingTriplet(vector<int>& nums) {
    
    
        int n = nums.size();
        if(n<3) return false;	//特判
        vector<int> min_(n);	//左边最小的数
        min_[0]=nums[0];	//从最左边开始遍历
        for(int i=1; i<n; ++i){
    
    	//注意i=1开始
            min_[i] = min(min_[i-1], nums[i]);
        }
        vector<int> max_(n);	//右边最大的数
        max_[n-1]=nums[n-1];	//从最右边开始遍历
        for(int i=n-2; i>=0; --i){
    
    	//注意i=n-2
            max_[i] = max(max_[i+1], nums[i]);
        }
        for(int i=1; i<n-1; ++i){
    
    	//注意i从1到n-2
            if(min_[i-1]<nums[i] && nums[i]<max_[i+1]){
    
    
                return true;
            }
        }
        return false;
    }
};

Otra solución 2: codicioso

Establezca primero<segundo, el valor inicial de primero es nums[0], segundo es ∞ y el puntero comienza a atravesar tercero:
si tercero>segundo, devuelve verdadero directamente;
si tercero<segundo pero tercero>primero, deje que segundo apunte a tercero ;
si tercero <primero, deje que el primero apunte al tercero.

class Solution {
    
    
public:
    bool increasingTriplet(vector<int>& nums) {
    
    
        int n = nums.size();
        if(n<3) return false;	//特判
        int first = nums[0], second = INT_MAX;	//注意∞的写法
        for(int i=0; i<n; ++i){
    
    
            int num = nums[i];
            if(num>second){
    
    	//third>second
                return true;
            }else if(num>first){
    
    	//third<second但是third>first
                second = num;
            }else{
    
    	//third<first
                first = num;
            }
        }
        return false;
    }
};

Tema: 238. Producto de matrices distintas a sí misma.

Mi solución: configurar las matrices de productos izquierda y derecha

La complejidad del tiempo y la complejidad del espacio son O (n)

class Solution {
    
    
public:
    vector<int> productExceptSelf(vector<int>& nums) {
    
    
        int n = nums.size();
        vector<int> left_mul(n);
        left_mul[0] = 1;	//设置第i个位置左边所有数的乘积
        for(int i=1; i<n; ++i){
    
    
            left_mul[i] = left_mul[i-1] * nums[i-1];
        }
        vector<int> right_mul(n);
        right_mul[n-1] = 1;	//设置第i个位置右边所有数的乘积
        for(int i=n-2; i>=0; --i){
    
    
            right_mul[i] = right_mul[i+1] * nums[i+1];
        }
        vector<int> answer(n);
        for(int i=0; i<n; ++i){
    
    	//第i个位置的answer等于左边所有数的乘积*右边所有数的乘积
            answer[i] = left_mul[i] * right_mul[i];
        }
        return answer;
    }
};

Otras soluciones: use la respuesta como left_mul y el número real R como right_mul

class Solution {
    
    
public:
    vector<int> productExceptSelf(vector<int>& nums) {
    
    
        int n = nums.size();
        vector<int> answer(n);
        answer[0] = 1;
        for(int i=1; i<n; ++i){
    
    	//answer首先作为left_mul
            answer[i] = answer[i-1] * nums[i-1];
        }
        int R = 1;
        for(int i=n-1; i>=0; --i){
    
    	//使用实数R遍历右侧乘积,乘到answer上
            answer[i] = answer[i] * R;
            R = R*nums[i];
        }
        return answer;
    }
};

Tema: 560. Subarreglo cuya suma es K

Creo que lo más importante de esta pregunta es entender que la pregunta requiere encontrar un subarreglo de i a j cuya suma sea k. Pasar de i a j es muy espiritual.

Solución 1: método brutal (tiempo de espera)

Complejidad del tiempo O (n ^ 3)

class Solution {
    
    
public:
    int subarraySum(vector<int>& nums, int k) {
    
    
        int n = nums.size(), count=0;
        for(int i=0; i<n; ++i){
    
    	//遍历i
            for(int j=i; j<n; ++j){
    
    	//遍历j
                int sum=0;
                for(int u=i; u<=j; ++u){
    
    	//i到j求和
                    sum += nums[u];
                }
                if(sum==k) ++count;	//求和结束判断是否为k
            }
        }
        return count;
    }
};

Solución 2: eliminar operaciones duplicadas en 1 (tiempo de espera)

class Solution {
    
    
public:
    int subarraySum(vector<int>& nums, int k) {
    
    
        int n = nums.size(), count=0;
        for(int i=0; i<n; ++i){
    
    
            int sum=0;
            for(int j=i; j<n; ++j){
    
    	//i到j == i到j-1 + j
                sum += nums[j];
                if(sum==k) ++count;
            }
        }
        return count;
    }
};

Solución 3: suma de prefijo

Suma de prefijo: la suma del elemento 0 al elemento x se
define como la matriz PreSum, PreSum[x] representa la suma del elemento 0 al elemento x
P re S um [ x ] = nums [ 0 ] + nums [ 1 ] + . . . . . . + números [ x ] Suma previa[x] = números[0]+números[1]+......+números[x]P re S u m [ x ]=números [ 0 ] _ _ _+números [ 1 ] _ _ _+......+n u m s [ x ]
entonces tenemos:
P re S um [ x ] = P re S um [ x − 1 ] + nums [ x ] PreSum[x] = PreSum[x-1]+nums[x]P re S u m [ x ]=P re S u m [ x1 ]+n u m s [ x ]
nums [ x ] = P re S um [ x ] − P re S um [ x − 1 ] nums[x] = PreSum[x]-PreSum[x-1]números [ x ] _ _ _=P re S u m [ x ]P re S u m [ x1 ]
Por lo tanto la suma de i a j es:
nums [ i ] + . . . . . . + nums [ j ] = P re S um [ j ] − P re S um [ i − 1 ] = k nums[i ] +......+numeros[j] = SumaPre[j]-SumaPre[i-1]=knúmeros [ i ] _ _ _+......+núm s [ j ] _ _=P re suma [ j ] _ _P re S u m [ i1 ]=k
en ese momentoi=0 ,i-1=-1, por lo que está especialmente definido.PreSum[-1]=0
Por lo tanto, la pregunta seconviertela suma del subarreglo de elementosia a.En esta pregunta, no nos importa cuál de los dos elementos tiene la diferencia PreSum = k. Nos importa el número de veces que aparece la diferencia, por lo que introducimos un mapa hash para registrarlo.Antes de atravesar nums, ingrese{0,1}, lo que significa que la suma de 0 aparece una vez.Al atravesar nums, encuentre la suma del prefijo de cada elemento, Cuente el número de apariciones y preste atención alelemento con la clave en el mapa hash (tengo entendido que),los valores de se acumulan.jkPreSum[j]-PreSum[i-1]=k

PreSum[-1]=0
当前前缀和-kPreSum[i-1]=PreSum[j]-kPreSum[i-1]

class Solution {
    
    
public:
    int subarraySum(vector<int>& nums, int k) {
    
    
        int n = nums.size(), count=0;
        unordered_map<int, int> hash;	//存储前缀和和对应出现频次
        hash[0]=1;	//初始值为PreSum[-1]=0,因此hash的初始值为前缀和为0,出现次数为1
        int pre=0;	//前缀和初始值
        for(int i=0; i<n; ++i){
    
    
            pre += nums[i];	//递增计算pre前缀和
            if(hash.find(pre-k)!=hash.end()){
    
    	//如果能找到之前的前缀和=当前前缀和-k,则将之前的前缀和出现频次累加到count上
                count += hash[pre-k];
            }
            ++hash[pre];	//统计该前缀和对应频次
        }
        return count;
    }
};

Supongo que te gusta

Origin blog.csdn.net/qq_43606119/article/details/130297477
Recomendado
Clasificación