您的位置:首页 > 职场人生

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

2017-12-15 14:34 369 查看
 

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

求所有子数组的和的最大值。要求时间复杂度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     }


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: