[LeetCode] 152. Submatriz máxima de productos

1. Título

Dada una matriz de números enteros, busque la submatriz continua con el producto más grande en la matriz (la submatriz contiene al menos un número) y devuelva el producto correspondiente a la submatriz.

Ejemplo 1:

输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6

Ejemplo 2:

输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。

Dos, referencia

1. Recurrencia

Ideas:

Para obtener más detalles, comprenda el código y los comentarios. El tiempo de espera de ejecución, pero puede capacitarse para comprender la recursividad.

Código:

class Solution {
    
    
    int max = Integer.MIN_VALUE;

    public int maxProduct(int[] nums) {
    
    
        if (nums == null || nums.length == 0) {
    
    
            return -1;
        }
        helper(nums, 1, 0);
        return max;
    }


    // 1-最大连续子列积
    private void helper(int[] nums, int product, int i) {
    
    
    	// Terminator
        if (i == nums.length) {
    
    
            return;
        }
		
		// Current logic:比较历史最大值与当前值,历史最大值形成增益则保留,否则丢弃
        int select = nums[i] * product;
        int max_value = Math.max(nums[i], select); // compare num[i] ? product*num[i]
        max = Math.max(max_value, max);

		// Drill down:保留有效数据,下一层可能会用到
        helper(nums, nums[i], i + 1);
        helper(nums, select, i + 1); 
    }
}

    // 2-最大不连续子列积
    // private void helper(int[] nums, int product, int i) {
    
    
    //     if (i == nums.length) {
    
    
    //         return;
    //     }
    //     int select = nums[i] * product;
    //     int max_value = Math.max(product, select);  // 差异
    //     max = Math.max(max_value, max);
    //     helper(nums, product, i + 1);  // 重点差异
    //     helper(nums, select, i + 1);
    // }

Complejidad del tiempo: O (2 n) O (2 ^ n)O ( 2n )
Complejidad espacial: O (n) O (n)O ( n )

2. Recursión + memorización

Ideas: No.
Código: Ninguno.
Complejidad de tiempo: O (n) O (n)O ( n )
complejidad espacial: O (n) O (n)O ( n )

3. Planificación dinámica

versión 1

Ideas:

1、状态定义:DP[i][2]
DP[i][0]:最大值
DP[i][1]:最小值

2、转移方程:DP[i]=DP[i-1]*a[i]
DP[i][0] = a[i]>=0 ? DP[i-1][0]*a[i] : DP[i-1][1]*a[i]
DP[i][1] = a[i]>=0 ? DP[i-1][1]*a[i] : DP[i-1][0]*a[i]

return DP[i][0]

Código:

class Solution {
    
    
    public int maxProduct(int[] nums) {
    
    
        if (nums==null || nums.length==0) return 0;
        int[][] dp = new int[nums.length][2];
        int res=nums[0]; dp[0][0]=nums[0]; dp[0][1]=nums[0];
        for (int i=1; i<nums.length; i++) {
    
    
            dp[i][0] = Math.max( Math.max(dp[i-1][0]*nums[i], dp[i-1][1]*nums[i]), nums[i]);
            dp[i][1] = Math.min( Math.min(dp[i-1][0]*nums[i], dp[i-1][1]*nums[i]), nums[i]);
            res = Math.max(res, dp[i][0]);
        }
        return res;
    }
}

Complejidad de tiempo: O (n) O (n)O ( n )
complejidad espacial: O (n) O (n)O ( n )

Versión 2

Ideas:

De lo anterior se puede ver que DP [i] [0/1] solo depende del resultado de la última operación DP [i-1] [0/1], por lo que aquí se puede realizar la optimización del espacio. El código específico es el siguiente:

Código:

class Solution {
    
    
    public int maxProduct(int[] nums) {
    
    
        if (nums==null || nums.length==0) return 0;
        int currMax = nums[0], currMin = nums[0], ans = nums[0];
        for (int i = 1; i < nums.length; ++i) {
    
    
            int mx = currMax, mn = currMin;
            currMax = Math.max(mx * nums[i], Math.max(nums[i], mn * nums[i]));
            currMin = Math.min(mn * nums[i], Math.min(nums[i], mx * nums[i]));
            ans = Math.max(currMax, ans);
        }
        return ans;
    }
}

Complejidad de tiempo: O (n) O (n)O ( n )
complejidad espacial: O (1) O (1)O ( 1 )

Tres, referencia

1. Posiblemente la solución más simple con O (n) complejidad de tiempo
2. Submatriz de producto máxima
3. Hermano, hice mi mejor esfuerzo

Supongo que te gusta

Origin blog.csdn.net/HeavenDan/article/details/108982297
Recomendado
Clasificación