首尾相连的循环数组求其子数组最大值

结对成员

  曹坤  翟凯

题目

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

要求:

  输入一个整形数组,数组里有正数也有负数。

  数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。

  如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大。

  同时返回最大子数组的位置。

思路

  经过讨论,只需将数组扩展为2倍长度,array[i]=array[length+i];从第一个元素开始依

次五个元素为一组,共分为五组进行;分别求得五个最大子数组和,然后求其最大值。这种方法

很容易解决问题,但是分组的个数就是元素的个数,即需要循环计算length次 。   不过,我偶

然间发现,最大子数组的第一个元素之前的元素一定是负数,否则整个数组全为正数,所以一个

在元素足够大的循环数组中,有一个比较节省计算量的方法,就是只需考虑负数元素的后一个元

素是否为正数,如果为正数则以此元素开始五个元素组成数组计算其最大值,即循环计算的次数

与负数的个数有关而无需循环length次。

代码

#include<iostream>
#include<conio.h>
#include<ctime>
#define Max_Length 10
using namespace std;
int main()
{
    srand((unsigned)time(NULL));
    int * arr=new int[2*Max_Length];
    int result=0,r,sum,k=0,l=0,g=0,a,b=0,flag=0;
    int randoms,count1=0,count2=0,c1=0,c2=0;

    while(1)
    {
        cout<<"随机产生"<<Max_Length<<"个数值:\n"<<endl;
        for ( int i=0; i<Max_Length; i++ ) {
            randoms = ( -rand()%100 + ( rand()%100 ));
            arr[i] = arr[i+Max_Length] = randoms;
            cout<<"数组元素"<<i+1<<"分别为:"<<arr[i]<<endl;
        }

        for(int s=0; s<Max_Length; s++) {

            if(arr[s]<0 && g==s) {
                g++;
                if(a<arr[s])
                {
                    a=arr[s];
                }
                if(g==Max_Length)
                {
                    cout<<"最大数组之和:"<<a<<endl<<endl;
                }
            }
            if(arr[s]>0 && l==s) {
                l++;
                b+=arr[s];
                if(l==Max_Length)
                {
                    cout<<"最大数组之和:"<<b<<endl<<endl;
                }
            }

            if(arr[s]<0 && arr[s+1]>=0) {
                flag=1;
                r=arr[s+1];
                sum=0;
                for ( int t=0,j=s+1; j<s+Max_Length+1; j++ ) {
                    t++;
                    if ( sum>=0 )
                    { sum+=arr[j]; }
                    else
                    { c1=j; sum=arr[j]; }
                    if( r < sum ) {
                        count1=c1;
                        count2=c2;
                        r=sum;
                    }
                }
                if(result<r)
                {
                    result=r;

                }

            }
        }
        if(flag==1)
            cout<<"最大数组之和3:"<<result<<endl<<endl;
        result=a=b=arr[0];
        getch();
    }
    return 0;
}

截图

总结
我和同伴其实早就想到之前的解决方法了,这个是我自己最后想到的,在数组元素足够大时,

会有效地节省计算的次数。所以我认为,方法总是有的,但要找到更好的方法需要多思考才行。

  

时间: 2024-12-12 15:29:00

首尾相连的循环数组求其子数组最大值的相关文章

lintcode循环数组之连续子数组求和

v 题目:连续子数组求和 II 给定一个整数循环数组(头尾相接),请找出一个连续的子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.如果多个答案,请返回其中任意一个. v 样例 给定 [3, 1, -100, -3, 4], 返回 [4,0]. v 思路 1.如果不是循环数组,求解连续子区间和的思路如下: 首先设一个累加变量和sum和最大值变量maxN,[ld, rd]表示当前正在累加的区间,[lt,rt]表示最大和的区间.从左边开始一直累加,并初始当前区间[ld

关于求已知整数数组的连续子数组的最大和的方法

日期:2019.3.9 博客期:039 星期六 这次的标题就是题目——关于求已知整数数组的连续子数组的最大和的方法,打个比方:给予数组 { 1 , -2 , 3 , -1 , 0 , 2 } ,它的连续子数组的最大和就是取得 { 3 , -1 , 0 , 2 } 时的和 4 !就是说我们需要找到元素值和最大的子数组.我们大可以考虑几种方法: (1)先求出所有的子数组,再找出每一组的和,求出和的最大值 >>>>>>>(优化)>>>>>&

Task 4 求数组的连续子数组的最大和(团队合作)

小组成员:李敏.刘子晗 1.设计思想:由于已经做过这个题目,只要对之前的程序加上相应的测试和约束即可.我们两个人一起商议后,决定了程序的主框架和并列出了最终可以实现的功能.先要定义数组长度和上下限的变量,然后通过if语句对用户所给出的长度和数值进行判断看是否合法,如果不合法要重新输入.最后再加上之前求和的相应代码即可. 2.出现的问题:我们达成协议后,李敏负责编程,我负责测试.开始写程序,在写判断数值是否满足int整型范围的时候出现了错误,我在测试的时候发现她把小于号错写成了大于号,然后加以改正

输入一个整形数组(可能有正数和负数),求数组中连续子数组(最少有一个元素)的最大和。要求时间复杂度为O(n)(解决)

输入一个整形数组(可能有正数和负数),求数组中连续子数组(最少有一个元素)的最大和.要求时间复杂度为O(n). 输入描述: [重要]第一行为数组的长度N(N>=1) 接下来N行,每行一个数,代表数组的N个元素 输出描述: 最大和的结果 输入例子1: 8 1 -2 3 10 -4 7 2 -5 输出例子1: 18 思路:对输入的数组进行计算, import java.util.Scanner; public class Main { public static void main(String[]

求子数组最大值

设计思路:用户输入一个数组本次规定为4个数的数组,可根据需要进行修改,关于如何求出子数组中和的最大值:应该先明确最大值的来源数组一定包括原来数组中的最大值,因此找到这个最大值并记录下标,定义两个和的变量temp和temp1,从最大值下标开始逐一求和比较最终得到子数组最大的和. 源代码: package arrsum; import java.util.Scanner; public class Sum { public static void main(String[] args) { int

求连续子数组的和最大

题目描述:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 思路: 我们可以使用分治法或者减治法来处理这个问题. 分治法    目标:把1个大问题分成2个小问题,2个小问题还可以再分,直到问题规模小的可以简单解决. 将该数组等分成两个子数组,假如知道左右两侧两个数组的各自的最大子数组和,那么整个数组的最大子数组和可能为三种情况: 右侧数组的最大子数组和 左侧数组的最大子数组和 左右两侧数

子数组最大值02

合作过程:     由于上次作业设计思想不同,经过讨论采用了统一的设计思想.对于这次的作业我们一起进行讨论,我们统一利用二维数组完成一维数组的循环求子数组.我负责进行编码,丽萍负责进行代码的审查和代码的测试. 设计思想: 基于上次不循环一维数组求子数组的最大值. 1.将一维数组转化为二维数组,变相将其转化为循环.即二维数组每一行使一维数组依次向前移动一个数. 2.利用上次思想一次求出每行子数组的最大值. 2.1.定义两个数s,max用来更新子数组的最大值,从数组data[]的data[n-1]开

最大子数组问题(求连续子数组的最大和)

在<算法导论>第四章分治策略(Divider and Conquer)4.1节提出了最大子数组问题.其转化就是求数组a={1, -2, 3, 10, -4, 7 , 2, -5}中连续子数组的最大和. 对于这个问题,很容想到一种暴力求解的方法:简单地尝试对所有可能的的组合进行求和.对数组为n存在n*(n-1)/2中组合,然后对每个组合进行求和.即三个for循环遍历,求出数组中每一个子数组的和,最终求出这些子数组的最大的一个值.记Sum[i,...,j]为数组a中第i个元素到第j个元素的和(其中

求数组中连续子数组的最大和

问题: 求解数组中连续一段子数组和的最大值.例如:{31,-41,59,26,-53,58,97,-93,-23,84},最大值为59+26-53+58+97=187 思路: 计算出任意i到j之间连续子数组的和再比较必然能得到最大值,但时间复杂度为O(n^2),我们希望能找出线性时间的算法. 我们注意到,假如数组中全为正数,那么最大和必然为全部数相加:如果数组中有负数,并且如果加上某个负数,子数组的和小于0,则最大和子数组必然不包含这个负数. 基于此,给出以下代码: //计算数组中任何连续子数组