求整数数组中和最大的子数组的3种方法
来源:互联网 发布:中兴和华为知乎 编辑:程序博客网 时间:2024/06/06 12:58
输入一个整型数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。
使用三种方式实现,分别是蛮力法:bf_MaxSubArray,分治法:dc_MaxArray,和O(n)实现的单循环法find_max。
#include"stdio.h"#include"math.h"#include"time.h"#include"windows.h"#define MIN_INT -10000#define MAX_INT 10000typedef struct{int max_left;int max_right;int max;}maxinfo;maxinfo bf_MaxSubArray(int *a,int n){maxinfo max;max.max_left= 0;max.max_right= 0;max.max= MIN_INT;int tmp=0;for(int i=0;i<n;i++){for(int j=i;j<n;j++){tmp += a[j];if(tmp > max.max){max.max = tmp;max.max_left = i;max.max_right = j;}}tmp = 0;}return max;}maxinfo dc_FindMaxCrossingSubArray(int *a,int left,int mid,int right){maxinfo leftMax;leftMax.max_left= mid;leftMax.max_right = mid;leftMax.max= MIN_INT;int tmp = 0;for(int i=mid;i>=left;i--){tmp += a[i];if(tmp>leftMax.max){leftMax.max = tmp;leftMax.max_left = i;}}maxinfo rightMax;rightMax.max_left=mid+1;rightMax.max_right = mid+1;rightMax.max= MIN_INT;tmp = 0;for(int j = mid+1;j<right+1;j++){tmp += a[j];if(tmp>rightMax.max){rightMax.max = tmp;rightMax.max_right = j;}}leftMax.max += rightMax.max;leftMax.max_right = rightMax.max_right;return leftMax;}maxinfo dc_MaxArray(int *a,int left,int right){if(left==right){maxinfo sgele;sgele.max_left=left;sgele.max_right = right;sgele.max= a[left];return sgele;}else{int mid = (int)floor((left+right)/2);maxinfo tmp;maxinfo maxleft = dc_MaxArray(a,left,mid);maxinfo maxright = dc_MaxArray(a,mid+1,right);maxinfo maxcross = dc_FindMaxCrossingSubArray(a,left,mid,right);tmp = maxleft.max>maxright.max?maxleft:maxright;tmp = tmp.max>maxcross.max?tmp:maxcross;return tmp;}}void show(maxinfo max){printf("收益最大的是:%d号前买入,%d号后卖出,收益$%d/股.\n",max.max_left+1,max.max_right+1,max.max);}void find_max(int *ary,int ARYSIZE){int max=0;//保存最大和int curSum=0;//保存当前和int curStart=0;//当前和的起始位置int start=0;//最大和的起始位置int end=0;//最大和的终止位置for(int i=0;i<ARYSIZE;i++){if(i==0){curSum=max=ary[i];continue;}if(curSum<0){curSum=0;//与负数相加,和会减小,所以抛弃以前的和curStart=i;}//最大值已经被保存下来,所以请大胆的继续往前加curSum += ary[i];//当前和被保存为最大值,记录下它的起始位置和结束位置if(curSum>max){max=curSum;start=curStart;end=i;}}printf("和最大的子数组为:\n");for(int j=start;j<=end;j++){printf("%d ",ary[j]);}printf("= %d",max);}void main(){int n = 16;int a[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};//{-13,-3,-25,-20,-3,-16,-23,-18,-20,-7,-12,-5,-22,-15,-4,-7};//int i=clock();show(bf_MaxSubArray(a,n));printf("\n==============\n");find_max(a,n);printf("\n==============\n");printf("计算耗时:%dms\n",clock()-i);int mid = (int)floor((n-1)/2);show(dc_FindMaxCrossingSubArray(a,0,mid,n-1));maxinfo result;LARGE_INTEGER nFreq;LARGE_INTEGER nBeginTime;LARGE_INTEGER nEndTime;double time;QueryPerformanceFrequency(&nFreq);QueryPerformanceCounter(&nBeginTime); //开始result = bf_MaxSubArray(a,n);//dc_MaxArray(a,0,n-1);QueryPerformanceCounter(&nEndTime);time=(double)(nEndTime.QuadPart-nBeginTime.QuadPart)/(double)nFreq.QuadPart;printf("%f微妙\n",time);show(result);printf("\n"); }
其中最优方法的参考地址:求整数数组中和最大的子数组
- 求整数数组中和最大的子数组的3种方法
- 求整数数组中和最大的子数组
- 求整数数组中和最大的子数组
- 求数组中和最大的子数组
- 求数组中和最大的子序列
- 求数组中和最大的子序列
- 求数组中和最大的子数组(数组中和最大的子串)
- 求数组中和最大的子数组(数组中和最大的子串)
- 求数组中和最大的子数组【算法】
- C#求数组中和最大的连续子数组
- 求数组中和最大的子数组与始末下标
- 求数组中和最大的子数组并输出子数组序列
- 求一个整数数组的子数组的最大和
- 寻找数组中和最大的子序列
- 数组中和最大的递增子序列
- 如何查找数组中和最大的子序列
- 求数组中和最大的一串数据
- 第二题 求数组中和最大的子数组和其对应的位置
- imageNamed和dataWithContentsOfFile的区别
- C++接口与实现分离(转
- XE2 和D7 的对比:
- 对微信PHPdemo的分析
- 项目三 按总成绩输出
- 求整数数组中和最大的子数组的3种方法
- JVM监控工具介绍
- linux学习入门2——linux文件系統基本结构(linuxcast.net)(倒转树状结构、命名机制、查看文件类型)
- php通过xpath访问xml文件
- TM框架-MySQL版本(实现动态开发和权限管理)-附下载地址
- xml DTD验证
- C/C++中函数参数传递详解
- 从阿里云os和Google之争看开源协议
- STL中sort、priority_queue、map、set的自定义比较函数