题目:返回一个整数数组中最大子数组的和。
要求:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)
发表一篇博客文章讲述设计思想,出现的问题,可能的解决方案(多选)、源代码、结果截图、总结。
通过我们专业大佬的讲解终于懂得了怎么以O(n)的时间复杂度实现这个问题
思想:我们用一个数组储存以这个数组的第一个整数为开头的子数组的和,那么这个数组的所有子数组都可以通过以这个数组的第一个整数为开头的子数组减去另个以这个数组的第一整数为开头的子数组得到,那么我们只需选取以这个数组的第一个整数为开头的子数组的和的最大值减去以这个数组的第一个整数为开头的子数组的和的最小值(为负值),特殊情况 1,最小值的子数组成员多于最大值子数成员时,我们应该选取最大值的前面的子数组的最小值(小于零) 2,当第一个子数组为最大值时,即这个数组的第一个整数组成的子数组,此时直接输出即可。
代码如下:
package test3;
public class The_first_test {
public static void main(String[] args) {
int a[] = { -1, -2,-3, -3, -4, -5 };
int b[] = new int[a.length]; // 用于储存子数组的最大值
b[0] = a[0];
/**
* 统计所有以一开头的子数组
*/
for (int i = 1; i < a.length; i++) {
b[i] = b[i - 1] + a[i];
}
int max = b[0];
int mas, mis;
mas = mis = 0;
int min = b[0];
/**
* 比较这些子数组里的最大值和最小值
*/
for (int i = 1; i < b.length; i++) {
if (max < b[i]) {
max = b[i];
mas = i;
}
if (min > b[i]) {
min = b[i];
mis = i;
}
}
/**
* 判断最小子数组的成员个数是否大于最大子数组的成员个数
*/
if (mis > mas) {
min = b[0];
mis=0;
for (int i = 0; i <= mas; i++) {
if (min > b[i]) {
min = b[i];
mis=i;
}
}
}
/**
* 判断最小子数组的和值是否小于零
*/
if(mis!=0)
{
if (min <= 0)
System.out.println("最大子数组的值为" + (max - min));
else
System.out.println("最大子数组的值为" + max);
}else
System.out.println("最大子数组的值为" + max);
}
}
int a[] = { -1, -2,-3, -3, -4, -5 };
int b[] = new int[a.length]; // 用于储存子数组的最大值
b[0] = a[0];
/**
* 统计所有以一开头的子数组
*/
for (int i = 1; i < a.length; i++) {
b[i] = b[i - 1] + a[i];
}
int max = b[0];
int mas, mis;
mas = mis = 0;
int min = b[0];
/**
* 比较这些子数组里的最大值和最小值
*/
for (int i = 1; i < b.length; i++) {
if (max < b[i]) {
max = b[i];
mas = i;
}
if (min > b[i]) {
min = b[i];
mis = i;
}
}
/**
* 判断最小子数组的成员个数是否大于最大子数组的成员个数
*/
if (mis > mas) {
min = b[0];
mis=0;
for (int i = 0; i <= mas; i++) {
if (min > b[i]) {
min = b[i];
mis=i;
}
}
}
/**
* 判断最小子数组的和值是否小于零
*/
if(mis!=0)
{
if (min <= 0)
System.out.println("最大子数组的值为" + (max - min));
else
System.out.println("最大子数组的值为" + max);
}else
System.out.println("最大子数组的值为" + max);
}
}