题目:输入一个整形数组,数组里有正数也有负数.数组中一个或者连续的多个整数组成一个子数组.求所有子数组的和的最大值.
要求:时间复杂度为O(n)
例如: 输入的数组为{1,-2,3,10,-4,7,2,-5} 和最大的子数组为{3,10,4,-4,7,2}因此输出该子数组的和为18;
方法一:
设置max=arr[0],进行两次for循环,不断进行累加sum判断与max关系,最终便可以得到最大值
缺点:时间复杂度为O(n*n)
方法二
//如果一个数字累加arr[i], 加之前arr[i]是一个负数,则累加和肯定是小于arr[i]的。
//如果一个数字累加arr[i], 加之前arr[i]是一个正数,则累加和肯定是大于arr[i]的。
利用以上的关系,我们便可以设置max,sum为arr[0],从数组下边k=1进行查找,判断arr[i]正负值再进行累加.最后进行与max比较即可.
方法三:
进行动态规划
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
//动态规划
int FindMaxSonArr3(int *arr, int len)
{
int i = 0;
int sum = arr[0];
int max = arr[0];
for (i = 1; i < len-1 ; i++)
{
if ( sum+arr[i]<arr[i])
{
sum=arr[i];
}
else
{
sum = sum + arr[i];
}
if (sum>=max)
{
max = sum;
}
}
return sum;
}
//如果一个数字累加arr[i], 加之前arr[i]是一个负数,则累加和肯定是小于arr[i]的。
//如果一个数字累加arr[i], 加之前arr[i]是一个正数,则累加和肯定是大于arr[i]的。
int FindMaxSonArr2(int *arr, int len)
{
int sum = arr[0];
int i = 1;
int max = arr[0];
for (i = 1; i < len-1;i++)
{
if (sum<0)
{
sum=arr[i];
}
else
{
sum=sum+arr[i];
}
}
if (sum>max)
{
max = sum;
}
return max;
}
int FindMaxSonArr1(int *arr, int len)
{
int i = 0;
int j = 0;
int sum = 0;
int Max = arr[0];
for (i = 1; i < len; i++)
{
sum = 0;
for (j = i; j < len;j++)
{
sum = sum + arr[j];
if (sum>Max)
{
Max = sum;
}
}
}
return Max;
}
int main()
{
int arr[] = { 1, -2, 3, 10, -4, 7, 2, -5 };
int len = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", FindMaxSonArr1(arr, len)); //暴力算法 时间复杂度O(n*n)
printf("%d\n", FindMaxSonArr2(arr, len)); //时间复杂度为O(n)
printf("%d\n", FindMaxSonArr3(arr, len)); //动态规划
system("pause");
return 0;
}