剑指Offer(三十):连续子数组最大和

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HaloTrriger/article/details/80615869

题目大意是这样,给出一串数字,求出所有子串中最大的和。

我的第一感觉是穷举法,默认第一个数字为最大值Max。从第一个开始,找出由它构成所有子串的和,依次和Max比较,更新Max值;然后第二个数字开始向后找由它构成所有子串的和,依次和Max比较,更新Max值;然后是第三个…。最后Max就是最大的了。(为什么从每个数字向后找子串不加它之前的?因为之前的数字早就算过当时包括它的子串和了。)

代码如下:

int FindMaxSumOfSubArray(int array[], int size) 
{
    //给Max赋值,默认第一个是最大
    int Max = array[0];

    for (int i = 0; i < size; i++)//穷举找出
    {
        //每次都判断arr[i]是否大于Max
        int tmp = array[i];
        if (Max < tmp)
            Max = tmp;
        //向arr[i]后面的所有子串找最大值
        for (int j = i + 1; j < size; j++)
        {
            tmp += array[j];
            if (tmp > Max)
                Max = tmp;
        }
    }
    return Max;
}

当然,聪明的人用的是另一种高明的方法
定义两个变量,一个curMax,一个finalMax。curMax记录当前最大值,finalMax记录最终的最大值。
curMax将之前值的和记录下来(此时curMax是之前和的最大的值)。如果小于0,置为当前值;否则,累加。如果curMax大于finalMax,更新finaMax(finalMax是最终的最大值)。

代码如下:

int FindMaxSumOfSubArray(int array[], int size) 
{
    int curMax = array[0];
    int finalMax = array[0];

    //之前的最大值小于0,丢弃,置为现在的值
    //curMax小于0的话,若array[i]大于0,最大值为array[i],
    //若array[i]小于0,可以用保存着之前最大值finalMax和curMax比较
    for (int i = 1; i < size; i++)
    {
        if (curMax < 0)
            curMax = array[i];
        else
            curMax += array[i];
        //如果当前最大值大于之前最大,更新最大值
        if (curMax > finalMax)
            finalMax = curMax;
    }
    return finalMax;
}

为什么curMax小于0就丢弃呢?

因为curMax是负数。
1. arr[i] 是正数,arr[i] 和 arr[i] 与负数的和相比,大者应选arr[i]。
2. arr[i] 是负数,
①如果 arr[i] 比curMax大,arr[i] 和两个负数之和相比,大者应该选arr[i]。
②如果 arr[i] 比curMax小,arr[i] 赋给curMax,此时curMax并不是最大的。而之后与finalMax的判断语句,恰好与之前最大值作比较,将此时的curMax丢弃。做到了fianlMax始终保持着最大和。

最后,有什么疑问,或者质疑,欢迎留言给我。

猜你喜欢

转载自blog.csdn.net/HaloTrriger/article/details/80615869