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

日期:2019.3.9

博客期:039

星期六

  这次的标题就是题目——关于求已知整数数组的连续子数组的最大和的方法,打个比方:给予数组 { 1 , -2 , 3 , -1 , 0 , 2 } ,它的连续子数组的最大和就是取得 { 3 , -1 , 0 , 2 } 时的和 4 !就是说我们需要找到元素值和最大的子数组。我们大可以考虑几种方法:

  (1)先求出所有的子数组,再找出每一组的和,求出和的最大值 >>>>>>>(优化)>>>>>>>>求子数组的时候考虑负数的情况,并同时记录最大值

  (2)通过假设的方法,最大值一定存在于这个数组,所以先求出最大值,之后围绕最大值向两边延申使得问题得到解决>>>>>>>>>(经验证,方法错误)>>>>>>>>> { 5 , -1 , 7 , -20 , 9 } (取得11)

  (3)[个人思想方法]

    我们从输入的第一个正数开始,计算它们的和记作Tnum(正数和),直到输入的数是负数,开辟一个Fnum(负数和),记录从此之后的负数和,直到输入的下一个数是正数。此时,判断 Tnum + Fnum 的大小是否大于 0 ,[注:只有负数转正数的时候判断] ,大于的话就更新Tnum的值为Tnum + Fnum + p ( p 值为你本次输入的值) ,小于或等于的话取 Tnum 为 p 。在每一次的循环中记录 Tnum 和 p 最大值 ,也就是最后的结果了。

    [实例:{ -3 ,2 ,-1,0,3  ,3 ,-4,3 } ]

    我们从输入的第一个数开始,-3不是正数,跳过,2是正数,我们把它记录到 Tnum 中,Tnum = 2 ,之后直到输入的是负数,所以输入的 -1 是负数 ,我们把它记录到 Fnum 中,Tnum = 2 , Fnum = -1,之后输入的是 0 ,不是正数,记录到 Fnum中,Fnum = -1 + 0 = -1,再下一个输入的是 3 ,我们知道 3 是正数,所以进行判断,因为 Tnum + Fnum = 1 > 0 , 所以我们需要把 Tnum 更新成 Tnum + Fnum + p , 这样 Tnum = 2 + ( -1 ) + 3 = 4 , (如果第二个数是 1 ,我们就要把 Tnum 设成 3 了),之后继续,输入的 3 是正数,就继续 Tnum = 4 + 3 = 7 , 下一个是 -4 , 我们把 Fnum 更新成 -4 , [ 注 : Fnum 就是单纯的记录输入的两次正数之间的负数和 ],而且下一个是 3 ,我们知道 Tnum + Fnum > 0 , 所以Tnum =  7 + ( -4 ) + 3  = 6 , 最终我们得到了 p 的最大值 3 和 Tnum 的最大值 7 , 所以我们的结果就是 7 啦!

    实际结果:{ 2 , -1 , 0 , 3 , 3}

    我的代码:  

 1 void My_Way()
 2 {
 3     //定义长度
 4     int n;
 5     //输入长度
 6     cin>>n;
 7     //最大值
 8     int rmax = -10000;
 9     //正数总值
10     int Tnum = -10000;
11     //负数总值
12     int Fnum = 0;
13     //记录是否发生转变
14     int sis = 0;
15     //标记是第几程度
16     int attitude = 0;
17     //循环
18     for(int i = 0 ; i < n ; ++i)
19     {
20         int p;
21         cin>>p;
22         if(attitude==0)                    //---------------------------------------[寻找第一个正数]
23         {
24             if(p<=0)
25                 ;
26             else
27             {
28                 Tnum = p;
29                 attitude = 1;
30             }
31         }
32         else if(attitude==1)            //---------------------------------------[上一个数为正数]
33         {
34             if(p<0)
35             {
36                 if(sis==0)
37                 {
38                     sis = 1;
39                     Fnum += p;
40                 }
41                 else
42                     Fnum = p;
43                 attitude = -1;
44             }
45             else
46                 Tnum += p;
47
48             if(Tnum>rmax)
49                 rmax = Tnum;
50         }
51         else                            //---------------------------------------[上一个数为负数]
52         {
53             if(p>0)
54             {
55                 attitude = 1;
56                 if(Tnum + Fnum > 0)
57                     Tnum = (Tnum + Fnum) + p;
58                 else
59                     Tnum = p;
60             }
61             else
62                 Fnum += p;
63         }
64         /*
65         cout<<"p="<<p<<endl;
66         cout<<"rmax="<<rmax<<endl;
67         cout<<"(p>rmax)="<<(p>rmax)<<endl;
68         */
69         if(p>rmax)
70             rmax = p;
71         if(Tnum>rmax)
72             rmax = Tnum;
73     }
74     cout<<rmax<<endl;
75 }

My_Way

    我的这种方法,其实还有可以优化的地方,比如对于关系的判断啊! attitude 只能取得 -1 , 0 , 1 三个值,而我们对于它的判定有以下概率问题;

    目前,我的方法空间复杂度较低(没有使用数组),时间复杂度为 O( n ) ;

  1、取1个值,没有实际意义

  2、取2个值:

    attitude的判断值 :

    排列    0 1 -1     1 -1 0      ...

    <1> 1 1  查询3次   查询4次     ...

    <2> 1 -1  查询3次    查询4次     ...

    <3> -1 1  查询2次    查询6次     ...

    <4>-1 -1  查询2次    查询6次     ...

    对于attitude的判断次数的数学期望最小值为 2.5;

  3、取3个值

    attitude的判断值

    <1> 1 1 1    查询5次

    <2> 1 1 -1   查询5次

    <3> 1 -1 1     查询6次

    <4> 1 -1 -1         查询6次

    <5> -1 1 1     查询4次

    <6> -1 1 -1    查询4次

    <7> -1 -1 1    查询3次

    <8> -1 -1 -1   查询3次

    对于attitude的判断次数的数学期望最小值为 4.5;

   所以我写的应该是最优的判断顺序了!

  (4) 同学的宝贵方法

    

原文地址:https://www.cnblogs.com/onepersonwholive/p/10500200.html

时间: 2024-10-05 19:56:07

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

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

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

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

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

一个数组中连续子数组的最大和

//连续子数组的最大和     //{ 1, -2, 3, 10, -4, 7, 2, -5 };//最大子数组18     #include<iostream>     using namespace std;     bool g_InValid = false;     int FindGreatSumOfSubArray(int* arr, int size)     {     if (arr == NULL || size <= 0)     g_InValid = true

数组:连续子数组的最大和

题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1) 解题思路 对于一个数组中的一个数x,若是x的左边

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

在<算法导论>第四章分治策略(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个元素的和(其中

求数组中任何连续子数组的最大和,并打印最大子数组(求开始和结束下标)

//计算数组中任何连续子数组的最大和,并打印最大子数组(求开始和结束下标) //思路:1:当数组元素全为0时,输出最大的那个负数 //      2:当数组有正有负时,i=0遍历数组,从大于0的那个元素开始,记录此时的下标为shart(最大子数组起始下标),从start开始遍历剩下的元素,若元素和num大于max的值则更新max, //    且将此时的下标赋值给end(最大子数组终止下标),当num小于0则说明后面出现的(如果出现)最大子数组不可能包含这些元素,所以退出内层循环,继续外层循环,

输入一个整形数组(可能有正数和负数),求数组中连续子数组(最少有一个元素)的最大和。要求时间复杂度为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[]

【原题】求两个不相交的连续子数组的最大和

题目: 有一个整数数组n,a和b是n里两个互不相交的子数组.返回sum(a)+sum(b)的最大值. 分析: 新建两个数组left和right,left[i]表示n[0:i]的连续子数组的最大和,right[i]表示n[i:length-1]的连续子数组的最大和.left[i]+right[i+1]的最大值就是答案. int SumOfTwoSubarray(const vector<int> &n) { if (n.size() < 2) { throw exception()

编程算法 - 连续子数组的最大和 代码(C)

连续子数组的最大和 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一个整型数组, 数组里有正数也有负数. 数组中一个或连续的多个整数组成一个子数组.求所有子数组的和的最大值. 使用一个数保存当前和, 如果当前和为小于0,  则替换新值, 否则, 递加, 使用一个数保存临时最大值. 代码: /* * main.cpp * * Created on: 2014年6月29日 * Author: wang */ #include <stdio