Resumen de temas relacionados para aumentar las subsecuencias

Tabla de contenido

1. La secuencia creciente continua más larga

2. La subsecuencia ascendente más larga

3. El número de la subsecuencia creciente más larga

4. Subsecuencia creciente

5. La secuencia continua más larga


A continuación se muestran algunos temas relacionados con el aumento de subsecuencias. Algunos temas tendrán soluciones óptimas, pero el enfoque principal aquí es la práctica de la programación dinámica , por lo que solo se escriben programación dinámica o algunos métodos generales.

Antes de presentar estos temas, primero distinga entre lo que es una subsecuencia y lo que es una subcadena

Subsecuencia: la subsecuencia no es continua, como la secuencia  [4, 6, 5] es  [1, 2, 4, 3, 7, 6, 5] una subsecuencia

Subcadena: la subcadena es continua

1. La  secuencia creciente continua más larga

Entrada: [1,3,5,4,7]
Salida: 3
Explicación: La secuencia creciente continua más larga es [1,3,5], y la longitud es 3.
Aunque [1,3,5,7] también es una subsecuencia ascendente, no es continua porque 5 y 7 están separados por 4 en la matriz original. 

Esta pregunta se trata de aumentar la secuencia, pero el requisito es continuo, por lo que en realidad busca aumentar la subcadena

class Solution:
    def findLengthOfLCIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        if len(nums) == 1:
            return 1
        dp = [1]*len(nums) #代表连续递增序列的长度
        for i in range(1,len(nums)):
            if nums[i]>nums[i-1]: #如果后一个元素大于前一个元素,那长度+1
                dp[i] = dp[i-1]+1
        return max(dp) # 找出最大的那个数就是长度,不能是dp[-1],dp[-1]代表的是以最后一个元素结尾是最长连续递增序列,但是最后一个并不一定是最大的数。

2. La  subsecuencia ascendente más larga

Use programación dinámica para hacerlo, defina la matriz dp para representar la longitud de la subsecuencia, dp [i] representa cualquier elemento antes del i-ésimo elemento como punto de partida y la longitud de la subsecuencia ascendente hasta el final de i -th elemento , inicializado a 1, lo que significa que cada elemento puede al menos convertirse en una subsecuencia individualmente, y la longitud es 1 en este momento.

Después de recorrer cada elemento nums [i], recorra los elementos nums [j] en [0-i] desde el principio. Si nums [i]> nums [j], entonces se puede acceder a nums [i]. el elemento nums [j], es decir, dp [i] = dp [j] + 1 

Entonces, la ecuación recursiva es dp [i] = max (dp [i], dp [j] +1) 0 \ leq j <i, al final, todavía encontramos max (dp) en lugar de dp [-1]

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        dp=[1]*len(nums)
        for i in range(len(nums)):
            for j in range(i):
                if nums[i]>nums[j]:
                    dp[i] = max(dp[i],dp[j]+1)
        return max(dp)

Si el ciclo interno de esta pregunta atraviesa desde 0 cada vez, en realidad hay muchos recorridos repetidos, por lo que el ciclo interno puede usar la dicotomía para encontrar el primer número mayor que num [i] y luego reemplazarlo con num [i], no hay mucho que decir, el código es el siguiente:

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        res = []
        for num in nums:
            if not res or num>res[-1]:
                res.append(num)
            else:
                l=0
                r=len(res)-1
                while l<r:
                    mid = (l+r)//2
                    if res[mid]<num:
                        l = mid+1
                    else:
                        r = mid
                res[l]=num
        return len(res)

3. El número de la subsecuencia creciente más larga

Esta pregunta es muy similar a la anterior, excepto que hay un recuento adicional del número de la subsecuencia creciente más larga

class Solution:
    def findNumberOfLIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        dp = [1]*len(nums)
        count = [1]*len(nums)
        temp = 1
        res = 0
        for i in range(1,len(nums)):
            for j in range(i):
                if nums[i]>nums[j]:
                    if dp[j]+1>dp[i]:
                        dp[i] = dp[j]+1
                        count[i] = count[j]
                    elif dp[i] == dp[j]+1:
                        count[i]+=count[j]
            # temp = max(temp,dp[i])
        temp = max(dp)
        for i in range(len(nums)):
            if dp[i] == temp:
                res += count[i]
        return res

Cuando dp [j] +1> dp [i], significa que la nueva longitud se encuentra por primera vez, que es dp [j] +1. En este momento, cuenta [i] = cuenta [j], lo que indica  nums[i] el final más largo La combinación de subsecuencias crecientes es igual a la  nums[j] combinación actual

Cuando dp [j] +1 = dp [i], significa que la secuencia creciente de esta longitud se ha encontrado una vez, entonces  count[i]+=count[j],el número de combinaciones existentes más el recuento [j] es el número total de combinaciones

El último recorrido es encontrar la longitud más larga, y su recuento correspondiente es el resultado

También puede usar una matriz de árbol para esta pregunta. Actualmente, la capacidad es limitada, por lo que no sé cómo usar una matriz de árbol. Omitir

4. Subsecuencia creciente

Este problema ya no se debe a la programación dinámica, sino a la búsqueda en profundidad, similar al retroceso. Si utiliza la solución de retroceso general, lleva demasiado tiempo. El código es el siguiente

class Solution:
    def __init__(self):
        self.res = []
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        
        def dfs(temp,start,nums):
            if len(temp)>=2 and temp not in self.res:
                self.res.append(temp[:])
            for i in range(start,len(nums)):
                if not temp or nums[i]>=temp[-1]:
                    temp.append(nums[i])
                    dfs(temp,i+1,nums)
                    temp.pop()
        temp = []
        dfs(temp,0,nums)
        return self.res

Se puede ver que se necesitan más de 6.000 milisegundos para usar una colección para podar, todavía está tardando demasiado, puede usar un diccionario para podar.

class Solution:
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        res = []
        def dfs(start, tmp):
            dic = {}
            if len(tmp) > 1:
                res.append(tmp)
            for i in range(start, len(nums)):
                if dic.get(nums[i], 0):
                    continue

                if len(tmp) == 0 or nums[i] >= tmp[-1]:
                    dic[nums[i]] = 1
                    dfs(i + 1, tmp + [nums[i]])


        dfs(0, [])
        return res

El tiempo que consumía se redujo de repente.

5. La secuencia continua más larga

Déjelo vacío primero, aprenda y verifique la colección y luego mejórelo

Supongo que te gusta

Origin blog.csdn.net/Matrix_cc/article/details/106903435
Recomendado
Clasificación