• 数组和矩阵问题:数组中子数组的最大累乘积


    题目

      给定一个 double 类型的数组 arr, 其中的元素可正、可负、可 0,返回子数组累乘的最大乘积。例如, arr = [-2.5, 4, 0, 3, 0.5, 8, -1], 子数组 [3, 0.5, 8] 累乘可以获得最大的乘积 12,所以返回 12.

    要求

      如果 arr 的长度为 N,要求时间复杂度为 O(N), 额外空间复杂度为 O(1).

    难度

      两星

    解答

      所有的子数组都会以某一个位置结束,所以,如果求出以每一个位置结尾的子数组最大的累乘积,在所有的累乘积中最大的那个累乘积就是最终的结果。即结果=Max{以 arr[0] 结尾的累乘积, .... , 以 arr[arr.length-1] 结尾的累乘积}。

      如何求出所有以 i 位置(arr[i])结尾的累乘积呢?假设以 arr[i-1] 结尾的最小累乘积为 min, 以 arr[i-1] 结尾的最大累乘积为 max。那么,以 arr[i] 结尾的最大累乘积只有以下三种可能:

    • 可能是 max*arr[i]。例如,[3,4,5] 的最大累乘积是在算到 5 的时候,为 60。
    • 可能是 min*arr[i]。例如,[-2,3,-4] 的最大累乘积是在算到 -4 的时候,为 24。
    • 可能是 arr[i]。例如,[0.1,0.1,100] 的最大累乘积是在算到 100 的时候,为 100。

      这三种可能的值中最大的那个就作为以 i 位置结尾的最大累乘积,最小的作为最小累乘积,然后继续计算以 i+1 位置结尾的时候,如此重复,直到计算结束。

      具体实现过程请参考如下代码中 maxProduct 方法。

     1 public class Main {
     2     
     3     public static void main(String[] args) {
     4         double[] arr = {-2.5, 4, 0, 3, 0.5, 8, -1};
     5         System.out.println(new Main().maxProduct(arr));//12.0
     6     }
     7 
     8     public double maxProduct(double[] arr) {
     9         if(arr == null || arr.length == 0) return 0;
    10         
    11         double max = arr[0]; // max 表示以 arr[i-1]位置结尾的子数组的最大累乘积
    12         double min = arr[0]; // min 表示以 arr[i-1]位置结尾的子数组的最小累乘积
    13         double res = arr[0]; // 最大的累乘积
    14         double maxEnd = 0; //表示最大累乘积的一种可能:以 arr[i-1]位置结尾的子数组的最大累乘积*arr[i]
    15         double minEnd = 0; //表示最大累乘积的一种可能:以 arr[i-1]位置结尾的子数组的最小累乘积*arr[i]
    16         
    17         for(int i = 1, len = arr.length; i < len; i++){
    18             maxEnd = max * arr[i];
    19             minEnd = min * arr[i];
    20             max = Math.max(Math.max(maxEnd, minEnd), arr[i]);
    21             min = Math.min(Math.min(maxEnd, minEnd), arr[i]);
    22             res = Math.max(max, res);
    23         }
    24         
    25         return res;
    26     }
    27     
    28 }
  • 相关阅读:
    layaAir引擎制作游戏的图集动画、时间轴动画、和骨骼动画总结二
    layaAir引擎制作游戏的图集动画、时间轴动画、和骨骼动画总结一
    Flask 生成验证码 支持干扰线、噪点
    数组操作
    css_权威指南_选择符
    css权威指南_特指度
    *arg **kwargs
    一日一库—importlib
    一日一库—itertools
    FLask 流程图、上下文、上下文隔离原理
  • 原文地址:https://www.cnblogs.com/zlxyt/p/10524387.html
Copyright © 2020-2023  润新知