求最小子序列和,最小的正子序列和,最大子序列乘积问题

注意:以下解法建立在a数组中既包含正数也包含负数的基础上。

1、求最小子序列和

这个可以直接参考求最大子序列和中第四种方法

/*
     * 最小子序列
     */
    static int MaxSubsequenceSum(int a[]) {
        int ThisSum, MaxSum;
        ThisSum = MaxSum = 0;

        for (int i = 0; i != a.length; ++i) {
            ThisSum += a[i];
            if (MaxSum > ThisSum)
                MaxSum = ThisSum;
            else if (ThisSum > 0)//任何正的子序列不可能是最小子序列的前缀
                ThisSum = 0;
        }
        return MaxSum;
    }

2、求最小的正子序列和



         /*
     * 最小正子序列和
     */
    public static int minPositiveSum(int[] a) {
        int len = a.length;
        Node[] b = new Node[len + 1];
        for (int i = 0; i < len + 1; i++)
            b[i] = new Node();
        b[0].sum = 0;
        b[0].k = 0;

        for (int i = 0; i < len; i++) {
            b[i + 1].sum = b[i].sum + a[i];
            b[i + 1].k = i + 1;
        }

        sort(b);

        int min = 65532;
        int sum = 0;
        for (int i = 0; i < len; i++) {
            sum = b[i + 1].sum - b[i].sum;
            if (b[i].k < b[i + 1].k && sum > 0 && sum < min)
                min = sum;
        }
        return min;
    }

    // 排序
    public static void sort(Node[] b) {
        int len = b.length;
        int j = 0;
        for (int gap = len / 2; gap > 0; gap /= 2) {
            for (int i = gap; i < len; i++) {
                Node tmp = b[i];
                for (j = i; j >= gap && b[j - gap].sum > tmp.sum; j -= gap)
                    b[j] = b[j - gap];
                b[j] = tmp;
            }
        }
    }

    class Node {
    public Node() {
    }

    public int sum;
    public int k;
}

该做法是转别人的,链接地址为原文,现在还不明白什么意思,先记录下来以便日后查看。

三、最大子序列乘积

做法1、

static int maxPositiveSubMul(int a[]) {
        int maxMul, thisMul, i;

        maxMul = 1;
        thisMul = 1;
        for (i = 0; i < a.length; i++) {
            thisMul *= a[i];

            if (thisMul > maxMul)
                maxMul = thisMul;
        }
        return maxMul;
    }

做法2、—->该做法转别人的,链接地址是原文

/*
     * 最大子序列乘积---动态规划
     */
    static int maxSubsequenceMul(int a[], int n) {
        int[] maxA = new int[100];
        int[] minA = new int[100];
        maxA[0] = minA[0] = a[0];
        int ans = a[0];
        for (int i = 1; i < n; i++) {
            maxA[i] = max(max(a[i], minA[i - 1] * a[i]), maxA[i - 1] * a[i]);
            minA[i] = min(min(a[i], minA[i - 1] * a[i]), maxA[i - 1] * a[i]);
            ans = max(ans, maxA[i]);
        }
        return ans;
    }

    static int max(int a, int b) {
        if (a > b) {
            return a;
        } else {
            return b;
        }
    }

    static int min(int a, int b) {
        if (a < b) {
            return a;
        } else {
            return b;
        }
    }

对于做法2,核心: 每一步只需要记住其前一步的正数最大值和负数的最小值
举个例子:
maxA[i-1]=3
minA[i-1]=-2
此时的Ai=-1
由此可得
maxA[i+1]=-2*-1=2
minA[i-1]=3*-1=-3
根据这个例子便可推出关于maxA[i],minA[i]的方程

maxA[i] = max(max(a[i], minA[i - 1] * a[i]), maxA[i - 1] * a[i]);
minA[i] = min(min(a[i], minA[i - 1] * a[i]), maxA[i - 1] * a[i]);

To look at the sunny side of everything and make your optimism come true

你可能感兴趣的:(算法与数据结构)