美文网首页
最大连续子数组和

最大连续子数组和

作者: MinoyJet | 来源:发表于2017-07-31 11:02 被阅读0次

    最大连续子数组和

    题目描述:

    输入一个整型数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。,求所有子数组的和的最大值。

    分析和解法:

    解法一:暴力求解

    我们可以找出所有连续子数组,并求解它们的和,找出最大值。
    源代码如下:

    #include <iostream>
    #include <limits>
    
    using namespace std;
    
    int main()
    {
        int a[100];
        int n = 0;
        while(cin.peek() != '\n')  cin >> a[n++];
        int maxsum = INT_MIN;
        int currsum = 0;
        for (int i = 0; i < n; i++)
        {
            for (int j = i; j < n; j++)
            {
                for (int k = i; k <= j; k++)
                    currsum += a[k];
                if (currsum > maxsum)
                    maxsum = currsum;
                currsum = 0;  ////这里要记得清零,否则的话 currsum 最终存放的是所有子数组的和
            }
        }
        cout << maxsum << endl;
        return 0;   
    }
    

    分析:时间复杂度为 O(n ^ 3)。

    解法二:顺序扫描

    这种解法是按顺序一个一个的加到 currsum 中,如果 currsum < 0 ,那么 currsum 置为下一个元素,然后持续比较 maxsum 和 currsum 的大小,使得 maxsum 为最大值。
    源代码如下:

    #include <iostream>
    #include <limits>
    
    using namespace std;
    
    int main()
    {
        int a[100];
        int n = 0;
        while(cin.peek() != '\n')  cin >> a[n++];
        int maxsum = INT_MIN;
        int currsum = 0;
        for (int i = 0; i < n; i++)
        {
            if (currsum < 0)
                currsum = a[i];
            else 
                currsum += a[i];
            if (currsum > maxsum)
                maxsum = currsum;       
        }
        cout << maxsum << endl;
        return 0;   
    }
    

    分析:时间复杂度为 O(n)。

    解法三:动态规划

    这是一个很经典的动态规划问题。
    令 currsum 为当前最大子数组的和,maxsum 为最后要返回的最大子数组的和。对第 j+1 个元素有两种选择:要么放入前面找到的子数组,要么作为新子数组的第一个元素。

    currsum = max(a[j], currsum + a[j])
    maxsum = max(maxsum, currsum)

    源代码如下:

    #include <iostream>
    #include <limits>
    
    using namespace std;
    
    int main()
    {
        int a[100];
        int n = 0;
        while(cin.peek() != '\n')  cin >> a[n++];
        int maxsum = INT_MIN;
        int currsum = 0;
        for (int i = 0; i < n; i++)
        {
            currsum = (currsum + a[i] > a[i]) ? (currsum + a[i]) : a[i];
            maxsum = (maxsum > currsum) ? maxsum : currsum;     
        }
        cout << maxsum << endl;
        return 0;   
    }
    

    分析:时间复杂度为 O(n)。

    特别注意:

    • 注意解法二与解法三的异同

    参考资料:《编程之法》The Art of Programming By July

    相关文章

      网友评论

          本文标题:最大连续子数组和

          本文链接:https://www.haomeiwen.com/subject/zwyllxtx.html