一维回环数组求解最大子数组问题

 一、题目与要求

  题目:返回一个整数数组中最大子数组的和。
  要求:
    输入一个整形数组,数组里有正数也有负数。
    数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
    如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大。
    同时返回最大子数组的位置。
    求所有子数组的和的最大值。要求时间复杂度为O(n)

 二、设计思想

  通过上次求解简单一维数组的最大子数组问题的解决,我们找到了一种实现时间复杂为O(n)的方法,采用的是二分法和递归进行的解决,后来再次检查那个程序发现时间复杂度是O(logn),这次我们考虑使用一种更有效的方法来实现O(n),我们重新审视了这道题目,要实现时间复杂度尽可能小的话就要尽可能少的遍历数组,这样我们采取一种方法只需要遍历一次数组就可以找出最大子数组(具体实现方法见代码及其注释)。关于实现数组回环,我们的方法是定义一个二倍长数组来首尾存取两次待求数组,以此解决回环。

 三、源代码

  

 1 /*======================================================================
 2             # Author: TianYongTao && ZhangYaPeng
 3             # E-Mail: [email protected]
 4             # Last modified: 2015-03-28 20:48
 5             # Filename: Demo.cpp
 6             # Description: 计算一维回环数组中的最大子数组并将其输出
 7 ======================================================================*/
 8 # include <iostream>
 9 using namespace std;
10 # define LENGTH 5
11
12 int MaxSubArr(int * arr,int & start,int & count) //start保存最大子数组起始点  count保存最大子数组长度
13 {
14     int max = 0;
15     int max1 = arr[0];                  //max1保存的是全部为负数的数组中的最大值
16     int temp = 0;
17     bool flag=false;
18     for(int i=0;i<2*LENGTH;i++)         //判断数组元素是否全部小于零
19     {
20         if(arr[i]>0)
21         {
22             flag=true;
23         }
24         if(arr[i]>=max1)
25         {
26             max1=arr[i];
27             start = i;
28         }
29     }
30     if(!flag)
31     {
32         count=1;
33         return max1;              //返回全部是负数的数组中最大的那个负数
34     }
35     start=0;
36     for(int i=0;i<2*LENGTH;i++)   //数组不全小于零时遍历一遍求出最大子数组
37     {
38         temp+=arr[i];
39         count++;
40         if(temp>max)
41         {
42             max = temp;
43         }
44         if(temp<=0)              //如果在数组叠加过程中和小于0  则舍去  从该部分后面重新叠加
45         {
46             temp=0;
47             start=i+1;
48             count=0;
49         }
50         if(count==LENGTH)
51         {
52             if(arr[i]<0)
53             {
54                 count--;
55             }
56             return max;
57         }
58     }
59     return max;
60 }
61
62 int main()
63 {
64     int Arr[LENGTH];
65     int Array[2*LENGTH];       //以2倍首尾相接数组代替回环数组
66     int start=0;
67     int count=0;
68     cout<<"请输入"<<LENGTH<<"个整数(可正可负): ";
69     for(int i=0;i<LENGTH;i++)
70     {
71         cin>>Arr[i];
72     }
73     int k=0;
74     for(int i=0;i<2*LENGTH;i++)
75     {
76         Array[i] = Arr[k++];
77         if(k==LENGTH)
78         {
79             k=0;
80         }
81     }
82     int max = MaxSubArr(Array,start,count);
83     cout<<"最大子数组序列为:";
84     for(int i=0;i<count;i++)
85     {
86         cout<<Array[start+i]<<" ";
87     }
88     cout<<endl;
89     cout<<"最大子数组的和为:"<<max<<endl;
90     return 0;
91 }

  四、运行结果

  

  五、结果测试

  1.数组元素均为有序正数

  

  2.数组元素为乱序正数

  

  3.数组元素为有序负数

  

  4.数组元素为乱序负数

  

  5.数组元素为正负混合

  

  六、心得体会

    本次结对开发使我和队友田永涛逐渐意识到结对开发可以在一定程度上避免写代码时出现逻辑上的错误,并且结对开发时要充分表达自己的想法,这样才能寻求出一个对问题最优的解决方案,才能避免走弯路,我们的算法实现了时间复杂度O(n),难度上并不难,只是最初没有仔细分析到底该怎样去实现时间复杂度最小,只是一味的想考虑一些复杂的算法去解决这个问题,其实看似复杂的问题往往可能有巧妙地解决方法。

  

  

时间: 2024-10-20 02:01:07

一维回环数组求解最大子数组问题的相关文章

环形数组的最大子数组求解

然后再用一维数组求解最大子数组的方法即可.值得注意的是,子数组的长度不可超过n,在我程序中有所体现.最终,因为没有要求时间复杂度的问题,我选择 了遍历的方法求解了此问题. 1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int n; 6 cout<<"输入环形数组的长度:"; 7 cin>>n; 8 int *p; 9 p=new int[n]; 10 for(int i=

返回一个一维整数数组中最大子数组的和(环)

题目: 返回一个一维整数数组中最大子数组的和. 要求: 输入一个一维整形数组,数组里有正数也有负数. 一维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值. 设计思想: (1)存在三个一维数组.第一个用于存储 输入的数组:第二个用于存储不同子数组的最大值:第三个用于存储 起始点不同的数组的最大值. (2)1.定制输入整数的个数 2.创建第一个一维数组,将数字输入 3. 利用循环,将所存在的第一个数组的数,进行加法

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

要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n). 思路: 结对开发:张子超 马思勉 刚看到这个题目首先想到的是将随机产生的数组复制一遍放在原数组后面,然后再进行求解,后来在和马思勉的探讨中得到新的解决思路,首先按照求解整数数组方法,

一维数组求最大子数组(解决溢出问题)

一.题目要求 题目:返回一个整数数组中最大子数组的和. 要求: 要求程序必须能处理1000 个元素: 每个元素是int32 类型的: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二.设计思想 程序在宏里面定义出了数组长度的大小,在长度超过100万的时候程序直接崩溃,其实这并不是因为结果太大导致的数值溢出,而是因为内存溢出,我们的数组是定义在程序内部的,属于局部变量,存放位置在栈上

课堂练习(返回一个环状一维整数数组中最大子数组的和)

设计思路: (1)将循环数组拆为我们熟悉的以为数组 (2)通过每个数组元素在数组中位置前移一位来实现环的拆分(array[i1]=array[i1+1]) (3)在每次拆分后的数组中求出最大子数组和并记录到一个新的数组result[]中 (4)求出result[]中的最大值r作为循环数组的最大值 拆分后数组最大子数组喝的解决: (1)定义整数数组arr[i] (2)定义maxsum为最大子数组和并赋初值为arr[0] (3)定义一个中间变量temp由arr[0]计算子数组(连续的)的和当temp

求数组中最大子数组的和(二维环)

成员:林彦汝.张金 (这次角色调换,我主要负责代码复审,代码测试计划:张金负责程序分析,代码编程.) 题目: 返回一个二维整数数组中最大子数组的和 要求: 输入一个二维整形数组,数组里有正数也有负数. 二维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值. 思路: 在求一维环形数组和二维数组最大子数组的和的基础上,我们将两个的方法综合起来求解关于二维环形数组.假设原二维数组a[3][3]为 1 -2 3 1 -3

软件工程课堂练习:返回一个一维整数数组中最大子数组的和

题目:返回一个一维整数数组中最大子数组的和.要求:输入一个一维整形数组,数组里有正数也有负数.一维数组首尾相接,象个一条首尾相接带子一样.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值. 此次何琳琳负责程序分析,代码编程,张一博负责代码复审和代码测试计划. 经分析讨论设计思路如下: 1.定义一个长为20的数组,先对前10个数进行初始化,后10个数等于前10个数: 2.设置长度为10的循环依次以前十个数为头进行最大子数组的计算: 3,再设置一个数组用来存储

求一维数组的最大子数组1(结对开发)

题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n) 发表一篇博客文章讲述设计思想,出现的问题,可能的解决方案(多选).源代码.结果截图.总结. 结对开发的伙伴: 博客名:Mr.缪 姓名:缪金敏 链接:http://www.cnblogs.com/miaojinmin799/ 分析: 如果按照最笨的方法就是一个一个的比较先比较一个数的然后二个

分治法求解最大子数组问题

/*     本问题是求解最大子数组问题     普通方法的复杂度为n^2     现在尝试给出一种小于n^2的算法     当然数组中必须要有负数,不然没有意义     本例中使用分治策略 */ #include<stdio.h> #include<stdlib.h> //定义返回结构体 typedef struct result {     int left; //左索引     int right; //右索引     int sum; //最大和 }*Res; //求解包含