【IT笔试面试题整理】连续子数组的最大和

来源:互联网 发布:好看的美国电影 知乎 编辑:程序博客网 时间:2024/05/01 18:20

 

【试题描述】输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。

求所有子数组的和的最大值。要求时间复杂度O(n)。

思路:当我们加上一个正数时,和会增加;当我们加上一个负数时,和会减少。如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零,不然的话这个负数将会减少接下来的和。

 

【参考代码】

 

 1     public static int maxSum(int[] a) { 2         int sum = 0; 3         int b = 0; 4         for (int i = 0; i < a.length; i++) { 5             if (b < 0) 6                 b = a[i]; 7             else 8                 b += a[i]; 9             if (sum < b)10                 sum = b;11         }12         return sum;13     }

 

思路2:动态规划实现

/*
*问题:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。
*求所有子数组的和的最大值。要求时间负责度为O(n)。
*使用动态规划方法来实现:
*如果用函数f(i)表示以第i个数字结尾的子数组的最大和,那么我们需要求出max(f[0...n])。
*我们可以给出如下递归公式求f(i)
*     |-- array[i] 如果i==0或者f(i-1)<0
*f(i)=|
*     |-- f(i-1) + array[i] 如果f(i-1)>0
*这个公式的意义:
*   当以第(i-1)个数字为结尾的子数组中所有数字的和f(i-1)小于0时,如果把这个负数和第i个数相加,得到的结果反而不第i个数本身还要小,所以这种情况下最大子数组和是第i个数本身。
*   如果以第(i-1)个数字为结尾的子数组中所有数字的和f(i-1)大于0,与第i个数累加就得到了以第i个数结尾的子数组中所有数字的和。
*/ 

 1     public static int maxSumInSubArray(int[] array) { 2         int[] c = new int[array.length];// 用来记录以当前元素结尾(数组就到当前元素的位置为止)的子数组的最大和 3         int max = -1000;// 用来记录数组c[]中的最大值 4         int start = 0;// 记录数组中子数组的最大和的开始位置 5         int end = 0;// 记录数组中子数组的最大和的结束位置 6         int tmp = 0; 7  8         c[0] = array[0]; 9         for (int i = 1; i < array.length; ++i) {10             if (c[i - 1] > 0) {11                 c[i] = c[i - 1] + array[i];12             } else {13                 c[i] = array[i];14                 tmp = i;15             }16             if (c[i] > max) {17                 max = c[i];18                 start = tmp;19                 end = i;20             }21         }22         System.out.println("子数组最大和的起始位置:" + start + "~" + end);23         return max;24     }

 

阅读全文
0 0