zoukankan      html  css  js  c++  java
  • 数组和矩阵问题:数组中子数组的最大累乘积

    题目

      给定一个 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 }
  • 相关阅读:
    作为一个前端,可以如何机智地弄坏一台电脑?
    Mysql数据库字符集问题
    代码扫描工具 SonarQube Scanner 配置 & Jenkins 集成
    【C++】统计代码覆盖率(四)
    【Jenkins】各项配置
    python小知识点汇总
    MobaXterm使用
    PHP代码覆盖率
    golang代码覆盖率
    压测工具Locuse的使用
  • 原文地址:https://www.cnblogs.com/zlxyt/p/10524387.html
Copyright © 2011-2022 走看看