Leetcode 53. Suma máxima de subarreglo (problema clásico de programación dinámica + comprensión de "sin efecto secundario")

  • Leetcode 53. Suma máxima de subarreglo (problema clásico de programación dinámica + comprensión de "sin efecto secundario")
  • tema
    • Dada una matriz de números enteros, encuentre una subarreglo continuo con la suma más grande (la subarreglo contiene al menos un elemento) y devuelva su suma más grande.
    • Un subarreglo es una parte contigua de un arreglo.
    • 1 <= números.longitud <= 10^5
    • -10^4 <= números[i] <= 10^4
  • solución
    • Programación dinámica: dado que la matriz debe ser continua , cada elemento se puede definir como el punto de inicio del sufijo, y el valor máximo de todos los sufijos del elemento anterior se compara con el valor máximo de 0 (sin agregar ningún elemento). El estado definido en este momento es "sin efecto posterior"
    • Estado de definición (subproblema de definición) : dp[n] representa el valor máximo de todos los sufijos donde el elemento actual es el punto de partida del sufijo
    • Defina la ecuación de transferencia : dp[i]=max(0, dp[i-1])+nums[i], el resultado es max(dp[0...n-1])
    • Compresión espacial : dado que dp[i] solo está relacionado con dp[i-1], se puede desplazar con un valor
    • Complejidad temporal: O(n), Complejidad espacial: O(1)
  • Entendiendo "sin efecto secundario"
    • "Sin efecto posterior" está en la "Guía avanzada para la competencia de algoritmos" de Li Yudong, el extracto es el siguiente:
    • Para garantizar que el cálculo de los subproblemas se pueda realizar de forma secuencial y sin repetición, la programación dinámica requiere que los subproblemas resueltos no se vean afectados por etapas posteriores. Esta condición también se llama "sin efecto secundario". En otras palabras, el recorrido del espacio de estado por programación dinámica constituye un gráfico acíclico dirigido, y el recorrido es un orden topológico del gráfico acíclico dirigido. Los nodos en el gráfico acíclico dirigido corresponden a los "estados" en el problema, y ​​los bordes en el gráfico corresponden a las "transiciones" entre estados. La selección de transiciones es la "decisión" en la programación dinámica.

    • Comprensión: cada subproblema solo se resuelve una vez, y la adición de elementos posteriores o la solución de subproblemas no afectará a los subproblemas resueltos previamente
  • el código
    /**
     * 动态规划:由于数组需要连续、因此可以定义每个元素作为后缀起点,比较 前一个元素所有后缀的最大值 与 0(不加任何元素) 的最大值,
     * 定义动规数组 dp[n] 代表当前元素为后缀起点的所有后缀最大值,可得转移方程:dp[i]=max(0, dp[i-1])+nums[i],结果就是 max(dp[0..n-1])
     * 空间压缩:由于 dp[i] 仅与 dp[i-1] 相关,因此可以使用一个值滚动即可
     * 时间复杂度:O(n),空间复杂度:O(1)
     */
    private int solution(int[] nums) {
    
    
        // 判空
        if (nums == null || nums.length <= 0) {
    
    
            return 0;
        }

        // 定义 dp 与初始化
        int dp = nums[0];


        // 循环获取最大值 与 空间压缩
        int res = dp;
        int len = nums.length;
        for (int i = 1; i < len; i++) {
    
    
            dp = Math.max(0, dp) + nums[i];
            res = Math.max(res, dp);
        }

        return res;
    }

Referencia: Problema clásico de programación dinámica (entendiendo "sin efecto secundario")

Supongo que te gusta

Origin blog.csdn.net/qq_33530115/article/details/131083414
Recomendado
Clasificación