Likou 300. La subsecuencia incremental más larga (programación dinámica)

300. La subsecuencia creciente más larga

Darle una matriz de números enteros y encontrar la longitud de la subsecuencia estrictamente creciente más larga.

Una subsecuencia es una secuencia derivada de una matriz, que elimina (o no elimina) elementos de la matriz sin cambiar el orden de los elementos restantes. Por ejemplo, [3,6,2,7] es una subsecuencia de la matriz [0,3,1,6,2,2,7].

示例 1:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:

输入:nums = [0,1,0,3,2,3]
输出:4
示例 3:

输入:nums = [7,7,7,7,7,7,7]
输出:1
 

提示:

1 <= nums.length <= 2500
-104 <= nums[i] <= 104
 

进阶:

你可以设计时间复杂度为 O(n2) 的解决方案吗?
你能将算法的时间复杂度降低到 O(n log(n)) 吗?

respuesta:

Debido a que este tipo de secuencia de problemas se puede combinar aleatoriamente (es decir, siempre que el tamaño coincida con el aumento), y hay muchas formas de combinar este tipo, es difícil resolverlo si solo se usa el recorrido del bucle.

Entonces, para este tipo de problemas aparentemente "complejos", podemos considerar el uso de ideas de programación dinámica para resolver el problema. Esta pregunta es similar al número de la subsecuencia continua más larga de Likou .

Definimos dp [i] como la subsecuencia creciente más larga que termina con el subíndice i, por lo que encontramos una de las ecuaciones de transición dinámica:
dp [i] = max (dp [i], d [j] +1)
y también puede No termina con el subíndice i, por lo que hay:
Max = max (dp [i], max)
Tenga en cuenta que max es para todos los anteriores dp [i-1], dp [i-2], dp [i- 3], etc. Encuentre un valor máximo.

Explicación detallada:

La primera es descomponer el problema y requerir el número de la subsecuencia creciente más larga. Podemos dividirlo en la subsecuencia creciente más larga que termina con el último elemento, y la subsecuencia creciente más larga que no termina con el último elemento, y luego emparejar los dos. puede pedir max.
Así que lo mismo se aplica a cualquier situación.

Podemos definir dp [i] como la subsecuencia creciente más larga que termina con el elemento i-ésimo, dado que termina con el elemento i-ésimo, se dividirá en muchos casos, es decir, se conectará al elemento anterior. (Porque esta pregunta se puede conectar arbitrariamente) Dado que hay i-1 al frente, enumere cada vez y compárelo con el resultado anterior.

Entonces podemos obtener la ecuación de transición de estado:
dp [i] = max (dp [i], dp [j] +1);
(j <= i-1)
Porque no puedo terminar con la i-ésima, sino con i -1, i-2, i-3 ... end, entonces después de calcular cada dp [i], necesitamos comparar con cada uno de los anteriores, es decir, con dp [i-1], dp [i -1], dp [i-3] ...
Y la operación anterior es demasiado problemática, por lo que usamos una variable para registrar el valor máximo de las primeras, y solo comparamos el valor máximo con dp [i]. **

Codigo 1:

int Max(int x,int y)
{
    
    
    return x>y?x:y;
}
int lengthOfLIS(int* nums, int numsSize){
    
    
    int dp[numsSize+1];
    if(numsSize<2)
    {
    
    
        return numsSize;
    }
    for(int i=0;i<numsSize;i++)
    {
    
    
        dp[i] = 1;
    }
    int max = dp[0];
    for(int i=1;i<numsSize;i++)
    {
    
    
        for(int j=0;j<i;j++)
        {
    
    
            if(nums[j]<nums[i])
                dp[i] = Max(dp[i],dp[j]+1);//由于一直进行比较,所以dp[i]本身也在不断更新
        }
        max = Max(max,dp[i]);
    }
    return max; 
}

Codigo 2:

char a[100];memset(a,1,sizeof(a));

int lengthOfLIS(int* nums, int numsSize){
    
    
    /* 1、定义dp数组,存放当前节点的最长递增子序列值 */
    int dp[numsSize];
    for (int i = 0; i < numsSize; i++) {
    
    
        dp[i] = 1;
    }
    /* 2、定义返回值 */
    int res = 1;
    /* 3、外层循环遍历数组中所有节点 */
    for (int i = 0; i < numsSize; i++) {
    
    
        /* 3.1、内层循环从0到当前节点 */
        for (int j = 0; j < i; j++) {
    
    
            /* 计算当前节点的最长递增子序列长度 */
            if (nums[i] > nums[j] && (dp[i] < dp[j] + 1)) {
    
    
                dp[i] = dp[j] + 1;
            }
        }
        /* 3.2、比较节点的最长递增子序列长度赋给res */
        if (res < dp[i]) {
    
    
            res = dp[i];
        }        
    }
    /* 4、返回结果 */
    return res;
}

Supongo que te gusta

Origin blog.csdn.net/xiangguang_fight/article/details/115100351
Recomendado
Clasificación