本来是想看看算法导论的,遇到这个问题,书上写的完全不知道说的什么?看博客发现有很多方法,可惜我不太想看,自己想了下觉得这个问题应该不难。

using System;
namespace arraytest
{
class program
{
public static void Main(string[] args)
{
int[] array=new int[]{1,-2,5,-3,9,-4,7,2,-8,10};//求这个数组里面的最大连续子数组
int sum=0,maxleft=0,maxright=0;//定义从数组左边开始求和的最大值为maxleft,右边为maxright
int maxindexright=0,maxindexleft=0;//定义maxleft的索引为maxindexright,右边也一样
for(int i=0;i<array.Length;i++)
{
sum+=array[i];
if(sum>maxleft)
{
maxleft=sum;
maxindexright=i;
}
}
sum=0;
//找到最大的右下标后,以之为起点,求左下标
for(int i=maxindexright;i!=0;i--)
{
sum+=array[i];
if(sum>maxright)
{
maxright=sum;
maxindexleft=i;
}
}
Console.WriteLine("最大连续子数组的下标分别是:{0},{1}",maxindexleft,maxindexright);
Console.WriteLine("最大连续子数组的和为:{0}",maxright);
Console.ReadKey();
}
}
}
最大连续子数组的下标分别是:2,9
最大连续子数组的和为:18
证明:
其实我想说的是,你如果从左右起点开始求和的话,那么你找到的那个最大和的下标和最大连续子数组的下标是相同的。
反证法:假设不同,最大连续子数组的右下标比最大和的右下标大,多出来的那部分它的和一定为负数,因为如果为正数,
那么最大和的下标一定不是目前这个下标。但如果多出来的那部分和为负数,那么一定不是最大连续子数组,
因为最大连续子数组没必要多加上一个负数。
所以最大和右下标和最大连续子数组右下标只能相同。
反之,左下标也只能一样。我们从右端开始计数就明白了。
当然我上面,做了个简化,没有从最右端计数,而是从找到的最大右坐标开始计数,这个道理容易想通,我不多说。
算法复杂度不是很懂,但是这个算法主要是遍历了两次数组求和。复杂度应该和n的个数成正比。不知道求和会影响性能。
大家觉得怎么样?
还有大家平时是怎么学算法的,自学如何比较快的入门?
