返回一个整数数组中最大子数组的和
(1) : 题目要求: 输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。要求时间复杂度为O(n) 发表一篇博客文章讲述设计思想,出现的问题,可能的解决方案(多选)、源代码、结果截图、总结。 设计思想及代码和结果截图: 1.最开始的想法很简单,使用穷举法。我们列出所有的子数组之和,然后取出其中的最大值,代码如下:
2.之后,意识到老师提出的动态规划算法,于是在网上查阅了相关资料,发现了Kadane算法。这个算法是动态规划的一种具体应用,其设计思想也很好理解:对于数组a,用ci标记子数组a[0..i]的最大和,那么则有 ci=max{ai,ci−1+ai} 但仔细观察我们发现,若ci-1<=0 那么ci=ai。用e表示以当前为结束的子数组的最大和,以替代数组c,那么我们可以表示为:e=max{ai,e+ai}。代码实现如下:
。 之后,老师提出了进阶的问题,如果将数组变成一个循环数组(环形数组),即头尾相接,又该如何求解最大子数组的和呢?这次的问题不再有时间复杂度限制。 我们注意到,可以把问题分成两个部分:如果最大子数组的和在数组的下标范围内,那么就可以直接应用上面的Kadane算法,可如果最大子数组的和超出了下标范围,又该如何求解呢?我查阅了相关资料,在leetnode发现了一位大神提出的思路:跨越边界的情况可以对数组求和再减去无环的子数组的最小和,即可得到跨越边界情况下的子数组最大和。将两种情况的最大值取出,即是问题的解。下面是代码:
} (2) 题目要求: 要求数组从文件读取。 如果输入的数组很大, 并且有很多大的数字, 就会产生比较大的结果 (考虑一下数的溢出), 请保证你的程序能正常输出。 另外, 如果输入文件的参数有错误, 这个程序应该能正常退出, 并显示相应的错误信息。 任何输入错误都不能导致你的程序崩溃。 思路和代码: 可以看到,提出了新的要求,其中很明显的是数字溢出问题,和异常捕捉。对于数字溢出,我们可以使用BigInteger类,而异常捕捉直接try catch代码块即可。下面是代码和测试:
|