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 [ x−1 ]+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 [ x−1 ]
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 [ i−1 ]=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 elementosi
a 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.j
k
PreSum[j]-PreSum[i-1]=k
PreSum[-1]=0
当前前缀和-k
PreSum[i-1]=PreSum[j]-k
PreSum[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;
}
};