最大子数组问题

来源:互联网 发布:mac os vmware 镜像 编辑:程序博客网 时间:2024/05/01 08:48

最大子数组问题,背景是股票买卖,也就是求一个数组的连续子数组的最大和,这个数组的元素一定是有负数的,要不然一定是所有元素之和。


用分冶法解决这个问题。


a[low,high]的任何连续子数组a[i,j]所处的位置必然满足下列三种情况:

  • 完全位于左子数组a[low, mid]
  • 完全位于右子数组a[mid + 1, high]
  • 跨越中点

最大子数组一定是这三种情况的所有子数组的和最大者


而任何跨越中点的 子数组都由两个子数组a[i, mid] 和a[mid + 1, j]组成,只要求出形如a[i, mid] 和a[mid + 1, j]的最大子数组,然后将其合并即可。


#include <iostream>#include <stdlib.h>#define LENGTH 16using namespace std;typedef struct{    int low;int high;int sum;}parm;parm find_max_crossing_array(int number[], int low, int mid, int high){parm threeParm;int sum = 0;int leftsum = number[mid] - 1;int left;for(int i = mid; i >= low; i--){sum += number[i];if(sum > leftsum){leftsum = sum;left = i;} } sum = 0; int rightsum = number[mid + 1] - 1;int right;for(int i = mid+1; i <= high; i++){sum += number[i];if(sum > rightsum){rightsum = sum;right = i;}}threeParm.low = left;threeParm.high = right;threeParm.sum = leftsum + rightsum; return threeParm;} parm find_max_son_array(int number[], int low, int high){int mid;parm threeParmLeft;parm threeParmRight;parm threeParmCross;parm threeParm;//递归停止if(low == high){threeParm.low = low;threeParm.high = high;threeParm.sum = number[low];return threeParm;} else{mid = (low + high) /2;threeParmLeft = find_max_son_array(number, low, mid);threeParmRight = find_max_son_array(number, mid + 1, high);threeParmCross = find_max_crossing_array(number, low, mid, high);if(threeParmLeft.sum >  threeParmRight.sum && threeParmLeft.sum > threeParmCross.sum){return threeParmLeft;}else if(threeParmRight.sum >  threeParmLeft.sum && threeParmRight.sum > threeParmCross.sum){return threeParmRight;}else{return threeParmCross;}}}int main(){int number[LENGTH] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};parm threeParm;threeParm = find_max_son_array(number,0,LENGTH - 1);cout << threeParm.low << " " << threeParm.high << " " << threeParm.sum << endl;system("PAUSE");return 0;}


其他解法见http://www.cnblogs.com/AlgrithmsRookie/p/5882379.html

       


0 0
原创粉丝点击