求解连续子数组乘积的最大值

 1 package com.demo.acm;
 2 
 3 import java.util.*;
 4 
 5 public class Main2 {
 6 
 7     /**
 8      * 求解一个数组相邻数相乘的最大值 例如 1 2 3 0 3 7 :21 方法一:时间复杂度为O(n*n),统计每一个子序列乘积
 9      */
10     private static double computeMultip1(double[] numb) {
11         double result = numb[0];
12         double tmpresult = 1;
13         for (int i = 0; i < numb.length; i++) {
14             for (int j = i; j < numb.length; j++) {
15                 tmpresult *= numb[j];
16                 if (tmpresult > result)
17                     result = tmpresult;
18             }
19             tmpresult = 1;
20         }
21         return result;
22     }
23 
24     /**
25      * 方法二: 扫描一边序列,记录最大值,最小值,和当前最大值,最小值,主要是因为负数的出现, 当当前的最大值小于1时,设置为当前的序列值,
26      * 
27      * @param numb
28      * @return
29      */
30     private static double computeMultip2(double[] numb) {
31         double maxMul = numb[0];
32         double minMul = numb[0];
33         double minCur = numb[0];
34         double maxCur = numb[0];
35         double tmp;
36         for (int i = 1; i < numb.length; i++) {
37             if (maxCur < 1)
38                 maxCur = numb[i];
39             else
40                 maxCur *= numb[i];
41             minCur *= numb[i];
42             if (maxCur < minCur) {
43                 tmp = maxCur;
44                 maxCur = minCur;
45                 minCur = tmp;
46             }
47             maxMul = maxCur > maxMul ? maxCur : maxMul;
48             minMul = minCur > minMul ? minCur : maxMul;
49         }
50         return maxMul;
51     }
52 
53     /**
54      * 方法三:通过动态规划求解,考虑到可能存在负数的情况,我们用Max[i],来表示以a[i]
55      * 结尾的最大连续子序列的乘积,用Min[i]表示以a[i]结尾的最小的连续子序列的乘积值 那么状态转移方程为: Max[i]=max{a[i],
56      * Max[i-1]*a[i], Min[i-1]*a[i]}; Min[i]=min{a[i], Max[i-1]*a[i],
57      * Min[i-1]*a[i]}; 初始状态为Max[1]=Min[1]=a[1]。代码如下:
58      * 
59      * @param args
60      */
61     private static double computeMul3(double[] numb) {
62         double[] maxMul = new double[numb.length];
63         double[] minMul = new double[numb.length];
64         maxMul[0] = numb[0];
65         minMul[0] = numb[0];
66         double maxValue = numb[0];
67         for (int i = 1; i < minMul.length; i++) {
68             maxMul[i] = Math.max(Math.max(numb[i], maxMul[i - 1] * numb[i]),
69                     minMul[i - 1] * numb[i]);
70             minMul[i] = Math.max(Math.max(numb[i], maxMul[i - 1] * numb[i]),
71                     minMul[i - 1] * numb[i]);
72             maxValue = Math.max(maxMul[i], maxValue);
73         }
74         return maxValue;
75     }
76 
77     public static void main(String[] args) {
78         Scanner scanner = new Scanner(System.in);
79         int length = 0;
80         System.out.println("请输入测试数据");
81         while (scanner.hasNext()) {
82             length = scanner.nextInt();
83             double[] numb = new double[length];
84             for (int i = 0; i < numb.length; i++) {
85                 numb[i] = scanner.nextDouble();
86             }
87             double result1 = computeMultip1(numb);
88             double result2 = computeMultip2(numb);
89             double result3 = computeMul3(numb);
90             System.out.println("方法的结果:result1=" + result1 + "  result2="
91                     + result2 + " result3=" + result3);
92         }
93     }
94 }

一共使用了三种方法用于求解一个序列的子序列乘积的最大值

动态规划的关键是找一个状态转移方程

转载于:https://www.cnblogs.com/csxf/p/3460391.html

你可能感兴趣的:(求解连续子数组乘积的最大值)