连续子数组的最大和

来源:互联网 发布:剑三萝莉捏脸数据图 编辑:程序博客网 时间:2024/05/31 15:18

题目描述

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度至少是1)

算法一:

暴力出所有的子数组,然后求出最大和,时间复杂度略高。

算法二:

面对一个数组,我们从头到尾开始遍历,同时将第一个数组元素作为初始最大值,我们举一个例子,数组【1, -2, 3, 10, -4, 7, 2, -5】, 我们建立两个辅助变量,一个为max, 一个为sum, 首先遍历第一个元素,max = sum = 1, 当遍历到第二个元素的时候,1 + -2 = -1, 遍历到第三个元素的时候-1 + 3 = 2,2  < 3, 所以如果我们求连续子数组的最大和,为什么不从这里重新开始,于是将sum 与max进行比较,保留目前产生的最大值,同时向后继续遍历,直到结尾。

代码如下:

public static int FindGreatestSumOfSubArray(int[] array) {        if (array == null || array.length <= 0) {            return -1;        }        int max = array[0];        int sum = array[0];        for (int i = 1; i < array.length; i++) {            if (i == 0) {                max = sum = array[0];            } else if ((sum + array[i]) < array[i]) {                sum = array[i];            } else {                sum += array[i];            }            if (max < sum) {                max = sum;            }        }        return max;    }

算法三:

我们利用动态规划的思路来解决这个问题,如果f(i)表示以第i个元素结尾的连续子数组的最大和,那么当i等于0的时候,显然等于data[i], 当f(i - 1) < 0的时候,显然f(i) = data[i], 因为任何数加上一个负数,都会小于本身,当i != 0 而且 f(i - 1) > 0的时候,则f(i) = f(i -1 ) + data[i]。最后我们求出最大值即可。

代码如下:

  public static int getMaxEndWithI(int[] data, int i) {        if (i == 0) {            return data[i];        } else {            int f = getMaxEndWithI(data, i - 1);            if (f <= 0){                return data[i];            }else{                return f + data[i];            }        }    }    public static int FindGreatestSumOfSubArray2(int[] array) {        if (array == null || array.length <= 0) {            return -1;        }        int max = getMaxEndWithI(array, 0);        for (int i = 1; i < array.length; i++) {            int temp = getMaxEndWithI(array, i);            if (max < temp) {                max = temp;            }        }        return max;    }    public static int FindGreatestSumOfSubArray3(int[] array) {        if (array == null || array.length <= 0) {            return -1;        }        int f_1, f = 0;        int max = 0;        for (int i = 0; i < array.length; i++) {            if (i == 0){                max = array[0];                f_1 = array[0];                f = f_1;                max = f = f_1 = array[0];            }else{                f_1 = f;                if (f_1 < 0){                    f = array[i];                }else{                    f = f_1 + array[i];                }            }            if (f > max){                max = f;            }        }        return max;    }



0 0