26、连续子数组的最大和
题目
- HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
思路
- 本题目应该考虑三种情况:
1、 当输入的数组元素全部都大于0时,即都为正数:判断方法就是找到数组的最小值,如果最小值大于0,那么就是正数数组
2、 当输入的数组元素都是小于0的时候:判断方法就是找到数组的最大值,如果数组的最大值是小于0的,那么就是负数数组
3、 当输入的数组元素是有正数、负数时;那么就得单独考虑
代码
- 错误代码:最大和不一定是从起始位开始相加的,所以代码错误
import java.util.ArrayList;
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
ArrayList<Integer> resultlist = new ArrayList<Integer>();
int sum =0;
for(int i=0;i<array.length;i++){
sum+= array[i];
resultlist.add(sum);
}
int max = resultlist.get(0);
for(int i=0;i<resultlist.size();i++){
if(max < resultlist.get(i)){
max = resultlist.get(i);
}
}
return max;
}
}
- 牛客的结果
不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为0.00%
测试用例:
[1,-2,3,10,-4,7,2,-5]
对应输出应该为:
18
你的输出为:
17
修改代码
import java.util.ArrayList;
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
ArrayList<Integer> resultlist = new ArrayList<Integer>();
int sum =0;
int length = array[0];
for(int i=0;i<array.length;i++){
if(length < array[i] ){
length = array[i];
}
}
int minlength =array[0];
for(int i=0;i<array.length;i++){
if(minlength > array[i] ){
minlength = array[i];
}
}
//数组元素都为正数的判断方法
if(length<0){
return length;
}
//数组元素都为负数的判断方法
else if(minlength>0){
for(int i=0;i<array.length;i++){
sum+=array[i];
}
return sum;
}
//数组元素既有正数、也有负数的判断方法
else{
for(int i=0;i<array.length;i++){
//先把前两个元素添加到链表中
if(i==0 && i==1){
sum+= array[i];
resultlist.add(sum);
}
//如果下一个元素序号大于1,并且前几个元素的之和大于0,那么可以继续添加元素之和到链表中
else if(i>1 && sum>=0){
sum+= array[i];
resultlist.add(sum);
}
//如果下一个元素的序号大于1,并且前几个元素的之和小于0,意味着前面几个元素之和不可能是连续最大值
else if(i>1 && sum<0){
//清除链表的内容
for(int l=0;l<resultlist.size();l++){
resultlist.remove(l);
}
//确定下一次开始时,sum的就是当前访问的元素(重新初始化)
sum=array[i];
}
}
//选择链表中的最大的值
int max = resultlist.get(0);
for(int i=0;i<resultlist.size();i++){
if(max < resultlist.get(i)){
max = resultlist.get(i);
}
}
return max;
}
}
}
- 乔戈里代码
import java.util.*;
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
if(array.length <= 0)
return -1;
int realMax = array[0];
int currentMax = 0;//当前最大值
for(int i=0;i<array.length;i++)
{
if(currentMax + array[i] >= array[i])
{//当前最大值加上当前数组的数如果比数组当前这个数大,那么就累加
//这里得好好体会,因为前面连续和大于0,所以加上当前数连续和肯定变大!所以是可能的最大连续和
currentMax += array[i];
}else{
//如果当前连续最大和小于0,那么就把currentMax赋值为当前这个数组中的数,重新开始
currentMax = array[i];
}
if(currentMax > realMax)//每计算出一个当前最大连续和就和最后的要返回结果进行比较
realMax = currentMax;//更新
}
return realMax;
}
}