1、T(N)=O(N^3)

__int64 algorithm1(__int64 a[],__int64 n)    //T(N)=O(N^3)
{__int64 MaxSum = 0;__int64 ThisSum;for(__int64 i = 0; i < n; i++)  //i从零开始到最后一个数字{for(__int64 j = i; j < n; j++)  //j从i开始到最后一个数字{ThisSum = 0;//PS:第一轮循环k从0->0,0->1,0->2...0->n//PS:第二轮循环k从1->1,1->2,1->3...1->n//PS:第K轮循环k从k->k,k->k+1,k->k+2...k->n//PS:这样就遍历完序列中所有子序列的可能性for(__int64 k = i; k <= j; k++) //从i开始到j的数字相加ThisSum += a[k];if(ThisSum > MaxSum)    //大于最大子序列之和则替换MaxSum = ThisSum;}}return MaxSum;
}

2、T(N)=O(N^2)

__int64 algorithm2(__int64 a[],__int64 n)   //T(N)=O(N^2)
{__int64 MaxSum = 0;__int64 ThisSum;for(__int64 i = 0; i < n; i++)  //i从零开始到最后一个数字{ThisSum = 0;//PS:第一轮j从0->n,每循环一次,判断一次//PS:第二轮j从1->n,每循环一次,判断一次//PS:第J轮j从j->n,每循环一次,判断一次//PS:这样就遍历完序列中所有子序列的可能性for(__int64 j = i; j < n; j++)  //j从i开始到最后一个数字{ThisSum += a[j];if(ThisSum > MaxSum)    //大于最大子序列之和则替换MaxSum = ThisSum;}}return MaxSum;
}

3、T(N)=O(NlogN),底数为2

PS:用分治法,先将原序列分成相似的两个子序列,这样可以得出一个结论,
那就是最大子序列和要不在左子序列中,要不在右子序列中,要不在左子序列和右子序列的连接处
对左子序列递归求最大序列和,对右子序列求最大序列和,再将左右子序列连接起来,求连接处的最大序列和
最后比较就能求出整体最大序列和

__int64 MaxSubSum(__int64 a[],__int64 Left,__int64 Right)
{__int64 Center; //中间元素__int64 MaxLeftSum,MaxRightSum; //左右子序列最大序列和__int64 MaxLeftBorderSum,MaxRightBorderSum; //左右边界最大序列和__int64 LeftBorderSum,RightBorderSum;   //左右边界序列和if(Left == Right)   //递归出口if(a[Left] > 0) //当a[i]>0时,返回该元素return a[Left];else            //否则返回0return 0;Center  = (Left + Right) / 2;MaxLeftSum = MaxSubSum(a,Left,Center);  //递归求解左子序列MaxRightSum = MaxSubSum(a,Center + 1,Right); //递归求解右子序列MaxLeftBorderSum = 0;LeftBorderSum = 0;for(__int64 i = Center; i>= Left; i--)  //求左边界最大序列和{LeftBorderSum += a[i];if(LeftBorderSum > MaxLeftBorderSum)MaxLeftBorderSum = LeftBorderSum;}MaxRightBorderSum = 0;RightBorderSum = 0;for(__int64 i = Center + 1; i <= Right; i++) //求右边界最大序列和{RightBorderSum += a[i];if(RightBorderSum > MaxRightBorderSum)MaxRightBorderSum = RightBorderSum;}return max(max(MaxLeftSum,MaxRightSum),MaxLeftBorderSum+MaxRightBorderSum); //返回整体最大序列和
}__int64 algorithm3(__int64 a[],__int64 n)   //T(N)=O(NlogN),底数为2
{return MaxSubSum(a,0,n - 1);
}

4、T(N)=O(N)

推荐用这种算法

__int64 algorithm4(__int64 a[],__int64 n)     //T(N)=O(N)
{__int64 ThisSum = 0;__int64 MaxSum = 0;for(int i = 0; i < n; i++)  //i从零开始到最后一个数字{ThisSum += a[i];if(ThisSum < 0) //当a[j]+...+a[i] < 0,则舍弃i之前的所有序列,从i后继续累加ThisSum = 0;if(ThisSum > MaxSum) //求出当前序列的最大子序列和MaxSum = ThisSum;}return MaxSum;
}

5、数量级及其时间比较表格

Algorithm 1 2 3 4
Time O(N^3) T/N Rate O(N^2) T/N Rate O(NlogN) T/N Rate O(N) T/N Rate
Input Size(N) 10 0.903 0.0903 0.771 0.0771 0.734 0.0734 0.707 0.0707
100 1.069 0.01069 0.791 0.00791 0.784 0.00784 0.744 0.00744
1000 3.538 0.003538 0.952 0.000952 0.805 0.000805 0.78 0.00078
10000 3000 0.3 1.599 0.0001599 1.067 0.0001067 0.859 0.0000859
100000 3000000 30 73.844 0.00073844 1.255 0.00001255 1.125 0.00001125

6、源代码及其测试数据

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;__int64 algorithm1(__int64 a[],__int64 n)    //T(N)=O(N^3)
{__int64 MaxSum = 0;__int64 ThisSum;for(__int64 i = 0; i < n; i++)  //i从零开始到最后一个数字{for(__int64 j = i; j < n; j++)  //j从i开始到最后一个数字{ThisSum = 0;//PS:第一轮循环k从0->0,0->1,0->2...0->n//PS:第二轮循环k从1->1,1->2,1->3...1->n//PS:第K轮循环k从k->k,k->k+1,k->k+2...k->n//PS:这样就遍历完序列中所有子序列的可能性for(__int64 k = i; k <= j; k++) //从i开始到j的数字相加ThisSum += a[k];if(ThisSum > MaxSum)    //大于最大子序列之和则替换MaxSum = ThisSum;}}return MaxSum;
}__int64 algorithm2(__int64 a[],__int64 n)   //T(N)=O(N^2)
{__int64 MaxSum = 0;__int64 ThisSum;for(__int64 i = 0; i < n; i++)  //i从零开始到最后一个数字{ThisSum = 0;//PS:第一轮j从0->n,每循环一次,判断一次//PS:第二轮j从1->n,每循环一次,判断一次//PS:第J轮j从j->n,每循环一次,判断一次//PS:这样就遍历完序列中所有子序列的可能性for(__int64 j = i; j < n; j++)  //j从i开始到最后一个数字{ThisSum += a[j];if(ThisSum > MaxSum)    //大于最大子序列之和则替换MaxSum = ThisSum;}}return MaxSum;
}//PS:用分治法,先将原序列分成相似的两个子序列,这样可以得出一个结论,
//那就是最大子序列和要不在左子序列中,要不在右子序列中,要不在左子序列和右子序列的连接处
//对左子序列递归求最大序列和,对右子序列求最大序列和,再将左右子序列连接起来,求连接处的最大序列和
//最后比较就能求出整体最大序列和
__int64 MaxSubSum(__int64 a[],__int64 Left,__int64 Right)
{__int64 Center; //中间元素__int64 MaxLeftSum,MaxRightSum; //左右子序列最大序列和__int64 MaxLeftBorderSum,MaxRightBorderSum; //左右边界最大序列和__int64 LeftBorderSum,RightBorderSum;   //左右边界序列和if(Left == Right)   //递归出口if(a[Left] > 0) //当a[i]>0时,返回该元素return a[Left];else            //否则返回0return 0;Center  = (Left + Right) / 2;MaxLeftSum = MaxSubSum(a,Left,Center);  //递归求解左子序列MaxRightSum = MaxSubSum(a,Center + 1,Right); //递归求解右子序列MaxLeftBorderSum = 0;LeftBorderSum = 0;for(__int64 i = Center; i>= Left; i--)  //求左边界最大序列和{LeftBorderSum += a[i];if(LeftBorderSum > MaxLeftBorderSum)MaxLeftBorderSum = LeftBorderSum;}MaxRightBorderSum = 0;RightBorderSum = 0;for(__int64 i = Center + 1; i <= Right; i++) //求右边界最大序列和{RightBorderSum += a[i];if(RightBorderSum > MaxRightBorderSum)MaxRightBorderSum = RightBorderSum;}return max(max(MaxLeftSum,MaxRightSum),MaxLeftBorderSum+MaxRightBorderSum); //返回整体最大序列和
}__int64 algorithm3(__int64 a[],__int64 n)   //T(N)=O(NlogN),底数为2
{return MaxSubSum(a,0,n - 1);
}__int64 algorithm4(__int64 a[],__int64 n)     //T(N)=O(N)
{__int64 ThisSum = 0;__int64 MaxSum = 0;for(int i = 0; i < n; i++)  //i从零开始到最后一个数字{ThisSum += a[i];if(ThisSum < 0) //当a[j]+...+a[i] < 0,则舍弃i之前的所有序列,从i后继续累加ThisSum = 0;if(ThisSum > MaxSum) //求出当前序列的最大子序列和MaxSum = ThisSum;}return MaxSum;
}__int64 Random(__int64 m,__int64 n)    //指定范围内随机数
{__int64 pos,dis;if(m == n)  //m=n则表示范围内只有一个数字{return m;}else if(m > n)  //m>n则说明取[m,n]区间内数字{pos = n;dis = m - n + 1;return rand() % dis + pos;}else    //m>n则说明取[n,m]区间内数字{pos = m;dis = n - m + 1;return rand() % dis + pos;}
}void MakeRandomSequences(__int64 m,__int64 n,__int64 num)   //产生随机序列
{ofstream filerandom("G:\\sequences.txt");srand((int)time(NULL)); //根据时间产生相应种子值for(int i=0 ; i < num; i++){filerandom << Random(m,n) <<" ";if(!((i + 1) % 10)) //数据量逢十换行filerandom << endl;}filerandom.close();
}
int main()
{
//测试数据
//    __int64 a[] = {4,-3,5,-2,-1,2,6,-2};
//    __int64 n = 8;
//    cout << algorithm1(a,n) << endl;
//    cout << algorithm2(a,n) << endl;
//    cout << algorithm3(a,n) << endl;
//    cout << algorithm4(a,n) << endl;//    MakeRandomSequences(-1000,1000,100000);  //产生随机序列__int64 a[200000];__int64 n = 0;ifstream filesequ("G:\\sequences.txt");if(!filesequ.is_open())   //打开失败处理{cout<<"Error opening file";return -1;}while(!filesequ.eof()){filesequ >> a[n++];}filesequ.close();//PS:测试只需要把调用算法注释去掉
//    cout << algorithm1(a,n) << endl;
//    cout << algorithm2(a,n) << endl;
//    cout << algorithm3(a,n) << endl;cout << algorithm4(a,n) << endl;return 0;
}

最大子序列和的四种求解算法及其时间比较相关推荐

  1. php主要算法设计,四种排序算法设计(PHP)

    标签 详细分析 /** * 四种排序算法设计(PHP) * * 1) 插入排序(Insertion Sort)的基本思想是: 每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子文件中的适当 ...

  2. JVM之垃圾收集机制四种GC算法详解

    JVM之四种GC算法详解 目录: 什么是GC? GC算法之引用计数法 GC算法之复制算法(Copying) GC算法之标记清除(Mark-Sweep) GC算法之标记压缩(Mark-Compact) ...

  3. php四种基础算法:冒泡,选择,插入和快速排序法

    许多人都说 算法是程序的核心,一个程序的好于差,关键是这个程序算法的优劣.作为一个初级phper,虽然很少接触到算法方面的东西 .但是对于冒泡排序,插入排序,选择排序,快速排序四种基本算法,我想还是要 ...

  4. 【JVM】四种GC算法(分代收集+三种标记算法)

    目录 参考文章 四种GC算法 分代收集算法(理论) 标记清除算法 标记整理算法 标记复制算法 三种算法的优缺点 参考文章 JVM的4种垃圾回收算法.垃圾回收机制与总结_我是guyue,guyue就是我 ...

  5. java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)...

    转载地址:http://www.devba.com/index.php/archives/4581.html java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明); ...

  6. 关于几种排序算法的时间性能比较

    以前经常看到各种排序算法,今天也对以下6种排序算法的时间性能做了一次测试: 测试代码地址 1. 冒泡排序 O(n^2) /** 冒泡排序 @Param {[]int} arr 整形切片 */ func ...

  7. mysql java 日期格式化_(转)java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)...

    java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明);部分资料参考网络资源 1. java向MySQL插入当前时间的四种方式 第一种:将java.util.Date ...

  8. java实现子序列最大和_算法入门:最大子序列和的四种算法(Java)

    最近再学习算法和数据结构,推荐一本书:Data structures and Algorithm analysis in Java 3rd 以下的四种算法出自本书 四种最大子序列和的算法: 问题描述 ...

  9. 求最大子序列和的四种方法

    求一个给定序列的连续子序列中和最大的那个子序列的和,下边方法只求和,没有找出最大子序列. 用到的头文件和宏定义如下 #include "stdafx.h" #include< ...

最新文章

  1. HashSet 和 TreeSet的区别
  2. mpvue微信小程序动画_mpvue微信小程序系列
  3. 使用snmp4j实现Snmp功能(三)
  4. C# 不支持关键字: “.;database”。
  5. 深度 | 理解深度学习中的卷积
  6. 创建型模式、结构型模式和行为型模式_设计模式之创建型模式
  7. Android学习之Activity
  8. 【原创】brew 和 brew cask
  9. RabbitMQ学习——常见概念详解
  10. 浅谈Vue 中的 computed 和 methods 的使用
  11. Python入门篇-基础数据类型整型(int),字符串(str)和切片(slice)
  12. Android游戏SQL注入,关于Android contentprovider sql注入问题
  13. linux 列出指定目录下所有文件的 列表集合
  14. Photoshop - 新建纯色图层
  15. 应用,传输层协议和端口对应关系
  16. Win10添加Loopback网卡
  17. 【ROS2原理11】C++编程的要点
  18. TexStudio编写Latex碰到的问题
  19. HTML5 Web Audio Api-2 发声oscillator
  20. Docker安装Elasticsearch及安装中文分词插件

热门文章

  1. Linux下Apache安装与配置(详细步骤+代码+验证)
  2. Tomcat本地正常!但是部署到服务器后,mysql插入中文乱码问题解决!
  3. linux常用指令 查看端口占用情况
  4. 【Linux 命令】云服务器 ECS (CentOS) 开启防火墙操作
  5. 大数据 Hive spark Flink 关系
  6. [极客大挑战 2019]PHP
  7. C#LeetCode刷题-拒绝采样
  8. struts2中Action名称的搜索顺序
  9. 找软件开发开发工作_将求职变成开发项目
  10. g2是一种编程语言吗_我写了一种编程语言。 这也是您可以的方式。