Utilice tres preguntas de la entrevista para comprender la lógica básica de la programación dinámica (golpee mientras el hierro está caliente, la segunda)

Enlace al título original: 300. Subsecuencia ascendente más larga (LIS)

¡Haz clic aquí para conquistar el primero! ! !
Descripción del Título:

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].
 

Ejemplo 1:

Entrada: nums = [10,9,2,5,3,7,101,18]
Salida: 4
Explicación: La subsecuencia creciente más larga es [2,3,7,101], por lo que la longitud es 4.

Ejemplo 2:

Entrada: nums = [0,1,0,3,2,3]
Salida: 4

Ejemplo 3:

Entrada: nums = [7,7,7,7,7,7,7,7]
Salida: 1

 

inmediato:

    1 <= núm. Longitud <= 2500-104 <=
    núm. [I] <= 104

Fuente: LeetCode (LeetCode)
Enlace: https://leetcode-cn.com/problems/longest-increasing-subsequence
Copyright es propiedad de LeetCode . Para reimpresiones comerciales, comuníquese con la autorización oficial. Para reimpresiones no comerciales, indique la fuente.

Ideas de preguntas:

1. Una breve introducción a la programación dinámica

La Programación Dinámica (Programación Dinámica), conocida como dp, es una estrategia común para resolver problemas de optimización En términos generales, el uso de la programación dinámica para resolver problemas no es más que tres pasos.

1.1 Definir el estado (el estado es el problema original, la solución del subproblema), como definir el significado de dp (i)

1.2 Establecer el estado inicial (límite), como establecer el valor de dp (0)

1.3 Determinar la ecuación de transición de estado, como determinar la relación entre dp (i) y dp (i-1)

2. Entonces, usando estos tres pasos, veamos cómo resolver el problema anterior.

2.1 Suponiendo que el valor de nums es {10,2,2,5,1,7,101,18}, es obvio que la subsecuencia creciente máxima es {2,5,7,101} y {2,5,7,18}. Longitud 4

2.2 Definir estado

Suponiendo que dp (i) es la longitud de la subsecuencia creciente más larga que termina en nums [i], ¿qué significa? P.ej

nums [0], la subsecuencia ascendente más larga que termina en 10 es 10, por lo que dp (0) = 1

nums [1], la subsecuencia ascendente más larga al final de 2 es 2, por lo que dp (1) = 1

nums [2], la subsecuencia ascendente más larga al final de 2 es 2, por lo que dp (2) = 1

nums [3], la subsecuencia ascendente más larga al final de 5 es 2, 5, entonces dp (3) = dp (1) + 1 = dp (2) + 1 = 2, donde dp (1) y dp (2 ) Significa que los primeros 2 y los segundos 2 se pueden combinar con 5 para formar la subsecuencia ascendente superior

nums [4], la subsecuencia ascendente más larga al final de 1 es 1, por lo que dp (4) = 1

La subsecuencia ascendente más larga al final de nums [5], 7 es 2, 5, 7, por lo que dp (5) = dp (3) + 1 = 3

La subsecuencia ascendente más larga al final de nums [6], 101 es 2, 5, 7, 101, por lo que dp (6) = dp (5) + 1 = 4

nums [7], la subsecuencia ascendente más larga que termina en 18 es 2, 5, 7, 18, por lo que dp (7) = dp (5) + 1 = 4

Entonces podemos encontrar que el elemento que puede ser la subsecuencia ascendente más larga de empalme debe cumplir dos condiciones. Primero, el elemento actual debe ser mayor que el valor final de la subsecuencia ascendente más larga anterior. Debido a que está aumentando, debe ser mayor. , De lo contrario, no se puede empalmar. En segundo lugar, la longitud después del empalme es la más larga.

2.3 Ecuación de transición de estado

Atravesar j∈ [0, i)

Si nums [i]> nums [j], nums [i] se pueden empalmar después de nums [j] para formar una subsecuencia ascendente más larga que dp (j), la longitud es dp (j) + 1, entonces dp ( j) = max {dp (i), dp (j) + 1}

Si nums [i] <= nums [j], nums [i] no se pueden empalmar después de nums [j], omita este recorrido

2.4 Estado inicial

dp (0) = 1, debido a que solo hay un elemento, la longitud debe ser solo 1. Todos los dp (i) se inicializan a 1 por defecto, porque queremos evitar que {3,5,1,10} aparezca cuando i es igual a 2., es el elemento 1, entonces si dp (i) no se inicializa a 1, entonces en el código, el elemento 1 definitivamente saltará 3 y 5, dp (2) = 0, obviamente no cumple con el significado de la pregunta, porque solo hay un elemento Cuando, su longitud es 1, por lo que debe inicializarse a 1.

3. Si es demasiado oscuro, lo explicaré en un inglés sencillo.

Por ejemplo, ahora estás jugando King of Glory. Los elementos en la matriz nums [] son ​​el poder de combate de cada jugador. En dp (i) es el número de personas que forman un equipo que termina con i. Porque King of Glory es una batalla en equipo, cada equipo debe turnarse para elegir El capitán, en otras palabras, cada jugador que puede unirse al equipo es la fuerza del capitán y se selecciona en función de los mejores. Al igual que el equipo tiene dos personas {jugador del pueblo, jugador provincial }, entonces cuando este equipo está seleccionando personas, debe ser. Se espera que los jugadores del servicio nacional se unan y asuman el puesto de capitán. Por ejemplo, si hay un equipo con una fuerza de {2, 4, 5 , 10}, luego, cuando el equipo elija al próximo capitán, solo aquellos con una fuerza superior a 10 habrán calificado para unirse al equipo, los jugadores con un poder de combate de menos de 10 serán eliminados, y así sucesivamente, eventualmente el equipo con aparecerá el mayor número de personas. Ese tipo de equipo es la respuesta que necesitamos.

No digas tonterías, solo ve al código, para que los jueces entiendan más claramente, mi código no está escrito de manera concisa, agrego muchos comentarios al código, creo que los jueces pueden entender, si lo hice no escribes claro o si te equivocas, puedes comentar en el área o enviarme un mensaje privado

class Solution {
    public int lengthOfLIS(int[] nums) {
        if(nums == null || nums.length == 0) return 0;
        int[] dp = new int[nums.length];    //由于我是从0下标开始,所以不用nums.length+1
        int max = dp[0] = 1;    //假设只有一个元素,那么最长度就是1
        for(int i = 1; i < nums.length; i++){
            dp[i] = 1;      //如果出现当前的元素是比之前的每条子序列最末位的数小,说明不能加进去,所以当前的元素的拼成的子序列,只有它本身,也就是长度是1
            for(int j = 0; j < i; j++){     
            //如果出现当前的元素是没有比之前的每条子序列最末位的数大,说明不能加进去,就跳过
                if(nums[i] <= nums[j]) continue;
                //代码执行到这里,说明当前元素是比子序列最末位的数大,所以把这个元素加到末尾
                //所以才有dp[j] + 1
                dp[i] = Math.max(dp[i],dp[j] + 1);
                //取出较大值
                max = Math.max(max,dp[i]);
            }
        }
        //返回长度最长的值
        return max;
    }
}

Lo he visto todo aquí, ¿no piensas en hacer clic en un me gusta antes de irte? Si no te gusta, mi corazón será Bingbing.

Supongo que te gusta

Origin blog.csdn.net/qq_45798556/article/details/114880742
Recomendado
Clasificación