最大连续子序列和,最大连续子序列乘

这个问题很常见了,只要找到最优子结构就好办了

最优子结构为

max[i] = Math.max(max[i-1] + num[i], num[i])

其中max[i]为以第i个元素为右边界的子数组的最大值,num为输入的int数组

下面给出解法

public int maxSumArray(int[] num) {
        int max;
        if (num[0] > 0) {
            max = num[0];
        } else {
            max = 0;
        }
        int[] count = new int[num.length];
        count[0] = num[0];
        for (int i = 1; i < num.length; ++i) {
            count[i] = (count[i - 1] + num[i] > num[i]) ? (count[i - 1] + num[i]) : num[i];
            if (max < count[i]) {
                max = count[i];
            }
        }
        return max;
    }

  

其实,可以不用count数组,而只用一个count变量记录以左边元素为界的最大值即可,改写后如下

 

public int maxSumArray(int[] num) {
        int max = num[0];
        int count = num[0];
        for (int i = 1; i < num.length; ++i) {
            count = Math.max(count+num[i], num[i]);
            if (max < count) {
                max = count;
            }
        }
        return max;
    }

  

上面的问题是找到最大连续子序列和,还有一个类似的问题是最大连续子序列乘,就是找到一个连续的子序列,使这个子序列的连乘最大

比如,数组[2,6,-5,8]的最大连续子序列乘是12,就是2*6

这个问题的最优子结构为

f(k) = max( f(k-1) * A[k], A[k], g(k-1) * A[k] )

g(k) = min( g(k-1) * A[k], A[k], f(k-1) * A[k] )

f(k)表示,以第k个元素为结尾的子序列连乘的最大值

g(k)表示,以第k个元素为结尾的子序列连乘的最小值

代码如下

public int maxProduct(int[] A) {
        if (A == null || A.length == 0) {
            return 0;
        }
        int result = A[0];
        int max = A[0];
        int min = A[0];
        for (int i = 1; i < A.length; ++i) {
            int tmp = max;
            max = Math.max(Math.max(max*A[i], min*A[i]), A[i]);
            min = Math.min(Math.min(tmp*A[i], min*A[i]), A[i]);
            if (result < max) {
                result = max;
            }
        }
        return result;
}

  

代码很好理解了

 

posted @ 2015-03-02 17:07  Truezion  阅读(238)  评论(0)    收藏  举报