您的位置:首页 > 其它

分治策略之最大子数组问题

2017-08-02 15:22 351 查看

问题描述:

问题:一个整数数组中的元素有正有负,在该数组中找出一个连续子数组,要求该连续子数组中各元素的和最大,这个连续子数组便被称作最大连续子数组。比如数组{2,4,-7,5,2,-1,2,-4,3}的最大连续子数组为{5,2,-1,2},最大连续子数组的和为5+2-1+2=8。


解问题:

一、暴力解法:

#include<iostream>
using namespace std;

class solution
{
public:

int FIND_MAXMUM_SUBARRAY(int A[], int length)
{
int i, j;
int sum = 0;
for (i = 0; i < length; i++)
{
int cursum = 0;
for (int j = i; j < length; j++)
{
cursum += A[j];
if (cursum > sum)
{
sum = cursum;
}

}

}
return sum;
}

};

int main()
{
int A[9] = { -1,2,-5,3,2,7,3,-2,-3 };
solution S1;
cout << S1.FIND_MAXMUM_SUBARRAY(A, 9);
system("pause");
}


二、分治解法:

#include<iostream>
using namespace std;

class solution
{
public:

int FIND_MAXMUM_SUBARRAY(int A[],int low,int high)
{
if (low == high)
return A[low];
else
{
int mid = (low + high) / 2;
int leftmax, rightmax,  crossmax;

leftmax = FIND_MAXMUM_SUBARRAY(A, low, mid);
rightmax = FIND_MAXMUM_SUBARRAY(A, mid + 1, high);
crossmax = findcross(A, low,  high);
if (leftmax >= rightmax&&leftmax >= crossmax)
{
return leftmax;
}
else if (rightmax >= leftmax&&rightmax >= crossmax)
{
return rightmax;
}
else
return crossmax;
}

}
int findcross(int A[],int low,int high)
{
int left_sum = -1000;

int sum = 0;
int right_sum = -1000;
int mid = (low + high) / 2;

for (int i = mid; i>=0; i--)
{
sum += A[i];
if (sum > left_sum)
{
left_sum = sum;

}

}
sum = 0;
for (int i = mid + 1; i <=high; i++)
{
sum = sum + A[i];
if (sum > right_sum)
{
right_sum = sum;

}
}
return left_sum + right_sum;
}

};

int main()
{
int A[9] = { -1,2,-5,3,2,7,3,-2,-3 };
solution S1;
cout<<S1.FIND_MAXMUM_SUBARRAY(A, 0,8);
system("pause");
}


三 、线性解法:

#include<iostream>
/*
@author zsj

*/
using namespace std;

int find(int a[], int length)
{
int temp=0;
int max=0;
for (int i = 0; i < length; i++)
{
temp += a[i];
if (temp > max)
max = temp;
if (temp < 0)
temp = 0;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法导论