求连续子数组的最大和
一、题目:
这是一道考的烂的不能再烂的题目,但是依然有很多公司乐于将这样的题目作为笔试或面试题,足见其经典。 问题是这样的:一个整数数组中的元素有正有负,在该数组中找出一个连续子数组,要求该连续子数组中各元素的和最大,这个连续子数组便被称作最大连续子数组。比如数组{2,4,-7,5,2,-1,2,-4,3}的最大连续子数组为{5,2,-1,2},最大连续子数组的和为5+2-1+2=8。
二、解法:
解法一:暴力求解法
/* (1) 常规方法,时间复杂度O(n*n) (2) 先从第一个元素开始向后累加, (3)每次累加后与之前的和比较,保留最大值, (4) 再从第二个元素开始向后累加,以此类推 */ public static int maxSubSum1(int[] arr, int len) { int i, j; int maxSum = 0; //每次开始累加的起始位置的循环 for (i = 0; i < len; i++) { int curSum = 0; //向后累加的循环 for (j = i; j < len; j++) { curSum += arr[j]; if (curSum > maxSum) maxSum = curSum; } } return maxSum; }
解法二:线性时间算法(推荐)
/* (1) 最优方法,时间复杂度O(n) (2) 和最大的子序列的第一个元素肯定是正数 (3) 因为元素有正有负,因此子序列的最大和一定大于0 */ public static int maxSubSum(int[] arr, int len) { int i; int maxSum = 0; int curSum = 0;//子数组的和 for (i = 0; i < len; i++) { curSum += arr[i]; if (curSum > maxSum) maxSum = curSum; //如果累加和出现小于0的情况, //则和最大的子序列肯定不可能包含前面的元素, //这时将累加和置0,从下个元素重新开始累加 if (curSum < 0) curSum = 0; } return maxSum; }