Dada una
无序
matriz de enteros, encuentre la subsecuencia ascendente más larga长度
.
Nota: No es necesario que la subsecuencia sea continua aquí.
Ejemplo:
输入:[10, 9, 2, 5, 3, 7, 101, 18]
输出:4
解释:最长的上升子序列是[2, 3, 7, 101],长度为4
Descripción:
- Puede haber múltiples combinaciones de la subsecuencia ascendente más larga, solo necesita generar la longitud correspondiente.
- La complejidad de tiempo del algoritmo debe ser O (n ^ 2)
Avanzado:
- ¿Puede reducir la complejidad temporal del algoritmo a O (nlgn)?
Método uno: programación dinámica
Ideas:
Para definir los significados dp first array: dp[i]
expresado como nums[i]
el número de 结尾
la longitud más larga de la secuencia de subincrementos.
como:
índice | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
nums | 1 | 4 | 3 | 4 | 2 | 3 |
dp | 1 | 2 | 2 | 3 | 2 | ? |
El proceso de evolución del algoritmo es el siguiente:
De acuerdo con esta definición, nuestro resultado final (la longitud máxima de la subsecuencia) debe ser el valor máximo en la matriz dp, a saber:
int res = 0;
for(int i = 0; i < dp.length; i++){
res = Math.max(dp[i], res);
}
return res;
Encuentre la ecuación de transición de estado:
De acuerdo con nuestra definición anterior de matriz dp, y ahora quiero encontrar el dp[5]
valor, es decir, quiero encontrar nums[5] 为结尾
la subsecuencia creciente más larga.
nums[5] = 3
Dado que es una subsecuencia creciente, solo necesitamos encontrar las subsecuencias anteriores cuyo final sea menor que 3, y luego conectar 3 al final para formar una nueva subsecuencia creciente, y la longitud de esta nueva subsecuencia aumenta en uno.
Por supuesto, se pueden formar muchas subsecuencias nuevas, pero solo necesitamos la más larga, y la longitud de la subsecuencia más larga se puede usar como el valor de dp [5].
dp [5] = max {dp [0] + 1, nums [0] = 1 <nums [5] dp [4] + 1, nums [4] = 2 <nums [5] dp [5] = max \ begin {cases} dp [0] + 1, \ quad nums [0] = 1 <nums [5] \\ dp [4] + 1, \ quad nums [4] = 2 <nums [5] \ end {cases } d p [ 5 ]=m a x{ d p [ 0 ]+1 ,n u m s [ 0 ]=1<n u m s [ 5 ]d p [ 4 ]+1 ,n u m s [ 4 ]=2<n u m s [ 5 ]
La ecuación de transición de estado final es:
dp [n] = max {dp [i] + 1, i ∈ [0, n - 1] ynums [i] <nums [n]} dp [n] = max \ {dp [i] + 1, \ quad i \ in [0, n-1] \ quad y \ quad nums [i] <nums [n] \} d p [ n ]=m a x { d p [ i ]+1 ,yo∈[ 0 ,norte-1 ]y n dn u m s [ i ]<n u m s [ n ] }
El caso base es 1, y la matriz dp debe inicializarse a 1, porque la subsecuencia debe contener al menos a sí misma, por lo que la longitud mínima es 1.
import java.util.*;
class Solution {
public int findNumberOfLIS(int[] nums) {
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
int res = 0;
for(int i = 0; i < nums.length; i++){
for(int j = 0; j < i; j++){
if(nums[j] < nums[i]){
dp[i] = Math.max(dp[i], dp[j]+1);
}
}
res = Math.max(res, dp[i]);
}
return res;
}
}
Complejidad de tiempo: O (n ^ 2)
Complejidad espacial: O (n)
Método 2: ideas de búsqueda binaria
En cuanto a la idea de la búsqueda binaria, puede ver este artículo La subsecuencia creciente más larga del diseño de programación dinámica
class Solution {
public int findNumberOfLIS(int[] nums) {
int[] top = new int[nums.length];
int piles = 0;
for(int i = 0; i < nums.length; i++){
int poker = nums[i];
int left = 0;
int right = piles;
while(left < right){
int mid = left + (right - left)/2;
if(top[mid] > poker){
right = mid;
}else if(top[mid] < poker){
left = mid + 1;
}else{
right = mid;
}
}
if(left == piles) piles++;
top[left] = poker;
}
return piles;
}
}
Complejidad de tiempo: O (nlgn)
Complejidad espacial: O (n)