leetcode 152.乘积最大子数组

题目描述

给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
子数组 是数组的连续子序列。leetcode 152.乘积最大子数组_第1张图片

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-product-subarray
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题

定义一个二维数组dp[n][n], 每一个元素dp[i][j]记录从i位置到j位置的乘积,利用变量max实现每次更新dp之后记录当前乘积最大值

class Solution {
    public int maxProduct(int[] nums) {
        int max = nums[0], n = nums.length;
        int[][] dp = new int[n][n];
        dp[0][0] = nums[0];

        for(int i = 0; i< n;i++){
            for(int j = i; j< n;j++){
                if(i == j){
                    dp[i][j] = nums[i];
                }else{
                    dp[i][j] = dp[i][j-1] * nums[j];
                }
                max = Math.max(max, dp[i][j]);
            }
        }

        return max;
    }
}

好, 去提交
在这里插入图片描述

错了!!!!提示超出内存限制
接下来优化代码,发现该代码优化后的时间复杂度也会是O(n^2)

需要换个思路:
同时记录最大值和最小值,这样的话如果当前元素是正数那么就乘最大值,如果当前元素是负数就乘最小值

class Solution {
    public int maxProduct(int[] nums) {
        int n = nums.length;
        int[] maxF = new int[n];
        int[] minF = new int[n];
        System.arraycopy(nums, 0, maxF, 0, n);
        System.arraycopy(nums, 0, minF, 0, n);
        for (int i = 1; i < n; ++i) {
            maxF[i] = Math.max(maxF[i - 1] * nums[i], Math.max(nums[i], minF[i - 1] * nums[i]));
            minF[i] = Math.min(minF[i - 1] * nums[i], Math.min(nums[i], maxF[i - 1] * nums[i]));
        }

        int ans = maxF[0];
        for (int i = 1; i < n; ++i) {
            ans = Math.max(ans, maxF[i]);
        }
        return ans;
    }
}

leetcode 152.乘积最大子数组_第2张图片

附:System.arraycopy()有什么作用
System.arraycopy()是Java中的一个方法,它可以用来将一个数组中的一部分元素复制到另一个数组中。 它的目的是在效率方面提高数组操作。

该方法有多个重载,基本语法为:

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

其中各参数含义如下:

  • src: 源数组
  • srcPos: 源数组中被复制的起始位置
  • dest: 目标数组
  • destPos: 复制到目标数组中的起始位置
  • length: 要复制的元素个数

使用 System.arraycopy()方法可以避免手动循环,并且代码可读性更好,同时也能提升程序效率。

你可能感兴趣的:(leetcode,leetcode,动态规划)