首尾相接数组求子数组最大和

一、题目及要求:

返回一个整数数组中最大子数组的和

如果数组A[0]...A[j-1]首尾相邻,允许A[i-1]...A[n-1],A[0]...A[j-1]之和最大;同时返回最大子数组的位置。

二、设计思路:

对于这题本想延用一维数组的方法,不过由于数组进行了整合,始末位置无法判断。所以此种方法断然没有实现。

小伙伴曾说延用课上学生提供的方法,形成一个固定长度的窗口,依次相加比较。这不失为一个好方法。只可惜时间复杂度不是n。

于是上网查了点资料。思想有点引用网上的了。首先将为两种情况,一种是跨越a[n-1],a[0]的。一种是没有跨越的。

对于没有跨越的,方法很多。对于跨零点的,则可以转换成求其子数组最小和。由于数组总和确定。对于中间那段必定为最小和。总和减最小和求出最大和。对于两个最大和进行比较。得到最终结果。

三、代码

/*王童博  燕亚峰*/
#include<iostream.h>
#include<stdlib.h>
struct ret
{
    int max,start,end;       //用于存放最大值,及始末位置
};

struct ret max2(int arry[],int length)  //跨越arry[n-1]、arry[0]的最大和
{
    int total=0;
    int start1=0;
    int start2;    //起始位置
    int end=0;
    int sum=arry[0];
    int minsum=arry[0];
    for(int i=1;i<length;i++)
    {
        if(sum>0)
        {
            sum=arry[i];
            start1=i;
        }
        else
        {
            sum=sum+arry[i];

        }
        if(minsum>=sum)
        {
            minsum=sum;
            end=i;
            start2=start1;
        }
        total=total+arry[i];
    }
    total=total+arry[0];
    minsum=total-minsum;
    struct ret ret1={minsum,start2,end};
    return ret1;
}

struct ret max1(int arry[],int length)   //不跨越零点的最大和
{
    int start1=0;
    int start2;     //起始位置
    int end=0;
    int sum=arry[0];
    int maxsum=arry[0];
    for(int i=1;i<length;i++)    //求出相邻数组最小和
    {
        if(sum<0)
        {
            sum=arry[i];
            start1=i;
        }
        else
        {
            sum=sum+arry[i];

        }
        if(maxsum<=sum)
        {
            start2=start1;
            end=i;
            maxsum=sum;
        }
    }
    struct ret ret1={maxsum,start2,end};
    return ret1;
}

int main()
{
    srand((unsigned)time(0));
    int N;
    cout<<"输入元素个数:";
    cin>>N;
    int a[20];
    for(int i=0;i<N;i++)
    {
        a[i]=rand()%20-10;
        cout<<a[i]<<"  ";
    }
    cout<<endl;
    struct ret w=max2(a,N);   //调用max2函数,求跨越零点的最值
    struct ret q=max1(a,N);
    if(w.max>q.max)
    {
        cout<<"最大和为:"<<w.max<<"起始位置:"<<w.end+1<<"结束位置:"<<w.start-1;
    }
    else
    {
        cout<<"最大和为:"<<q.max<<"起始位置:"<<q.start<<"结束位置:"<<q.end;
    }
    return 0;
}

四、截图

五、实验总结

对于本次实验还是颇有感悟的,对于有些东西不能过于复杂化。像上次一维数组就可以很简单的解决。但自己却化蛇添足。多了几处不需要的代码。不过也是对自己思想的一种实现。

这次实验有点借用网上的了。从反方向入手,不失为一种很好的方法,让我想起TED中的一段演讲,凡事都要考虑反面,美国人在日本问街道的名称,得到的回答却是某某街区和某某街区。因为街道是没有命名的。

对于思路已在思路方面详细阐述了。在这里仅说反向考虑这种思想。

无论什么方面的事情,似乎都需要双方向考虑。

最后不得不附上努力思考的疲劳状:

时间: 2024-12-27 16:21:52

首尾相接数组求子数组最大和的相关文章

结对开发首尾相接数组求子数组最大和

组员:燕亚峰  20122914           王童博   20122823 一.题目及要求: 返回一个整数数组中最大子数组的和 如果数组A[0]...A[j-1]首尾相邻,允许A[i-1]...A[n-1],A[0]...A[j-1]之和最大:同时返回最大子数组的位置. 二.设计思路: 对于这题本想延用一维数组的方法,不过由于数组进行了整合,始末位置无法判断.所以此种方法断然没有实现. 可以形成一个固定长度的窗口,依次相加比较. 首先将为两种情况,一种是跨越a[n-1],a[0]的.一种

环状连续数组,求子数组最大和

今天看到环状连续数组求子数组最大和的题目,看了几篇博客,但是好像有问题,可以举出反例.于是参考其他人的博客自己又总结下. 首先,求非环状的数组中子数组 最大和问题是一个动态规划的思想. sum[i] = max(sum(i-1) + a[i], a[i]); sum[i]代表以i元素结尾的子数组的最大和,sum[i-1]代表以i-1元素结尾的子数组的最大和,a[i]代表第i个元素的值,由此公式可得,以第i个元素结尾的子数组的最大和可以由它之前的以第i-1个元素结尾的子数组的最大和推导出.如果以i

二维数组求子数组之和最大值(首尾相接, 圆柱)

问题:求二维数组的子数组之和的最大值(首尾相接,即形成圆柱) 成员: 陈晨:负责代码复审和代码测试计划 王颖瑞:负责程序分析,代码编程 思路:对于这个问题,我们可以结合之前的实验(二维数组求子数组之和的最大值和首尾相连一维数组的子数组之和的最大值),把为二维数组的列扩大二倍,之后想一维数组(首尾相连)一样,把二维数组分成不同的几个二维数组.之后就分开求不同的二维数组的子数组的最大值,最后之间比较,求出总的最大值. 代码: #include<iostream> using namespace s

环形数组求子数组和最大

题目:返回一个整数数组中最大子数组的和.要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1],…… A[n-1],A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值. 分析: 运用了第一次的实验返回数组的最大子数组和,就只是把环形数组变成了n次的数组. 但是我们没有保存每一次的最大值,只是比较了最大值,所以没有返回子数组的位置. #inc

一维数组连续子数组最大和

题目描述 输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组.求所有子数组的和的最大值. 输入描述 输入有多组数据,每组测试数据包括两行.第一行为一个整数n(0<=n<=100000),当n=0时,输入结束. 接下去的一行包含n个整数(我们保证所有整数属于[-1000,1000]). 输出描述 对应每个测试案例,需要输出一个整数单独一行,表示连续子向量的最大和. 输入样例 3 -1 -3 -2 输出样例 -1 测试代码 1 #include <stdio.h

输入一组整数,求子数组和的最大值。(数组进行首尾相接之后)

输入一组整数,求子数组和的最大值. 题目:返回一个一维整数数组中最大子数组的和. 要求: 输入一个一维整形数组,数组里有正数也有负数. 一维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值. ? 10 -9 8 7 -5 3 ? i : 4 3 2 1 0 ? nALL : 3 3 7 15 15 16 ? nStart: 3 -2 7 15 6 16 ? nStart = max(arr[i], arr[i]+

求一个数组的子数组的最大和

如题:求一个数组的子数组的最大和,要求O(n)时间复杂度. 由于有了O(n)时间复杂度的限制,所以暴力求解的O(n^2)方法肯定不行.再考虑递归求一个数组a[n]的子数组的最大和,可以分解为a[i]子数组的最大和以及a[n-i-1]之间的某种情况 a[n]的子数组最大和等于a[i]子数组的最大和: a[n]的子数组最大和等于a[n-i-1]: a[n]的子数组最大和跨a[i]和a[n-i-1]: 递归实现的时间复杂度为O(nlg(n)).最后考虑时间复杂度为O(n)的动态规划实现. /** *

Java实现:求子数组的最大和(数组)

求子数组的最大和(数组) 题目: 输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.要求时间复杂度为 O(n). 例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为 3, 10, -4, 7, 2,因此输出为该子数组的和 18. 解题思路: 我觉得用户关心的的数据有两个,一个是子数组的和,还有一个是子数组具体有哪些元素,所以我们可以封装一个子数组类SubArray,成员有子数据开

【编程题目】求子数组的最大和 ☆

3.求子数组的最大和(数组)题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.要求时间复杂度为 O(n).例如输入的数组为 1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为 3, 10, -4, 7, 2,因此输出为该子数组的和 18. 算法里学过,动态规划.具体思路想不起来了,看了看书.要动态算1-i个元素中必须包括第i个元素的最大子段和C[i],A是原始序列 C[i + 1] = A[