//求一个数组的最大子段和
//1.枚举法 时间复杂度O(n2)
//2.递推法 时间复杂度O(n)
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <ctime>
#define LEN 10
typedef int* intp;
typedef int** intpp;
using namespace std;
//随机生成一个数值为min到max的,大小为num的数组
intp randArray(int num)
{
srand((int)time(NULL));
intp arr = new int[num];
for (int i = 0; i < num; i++) {
arr[i] = rand() % 10 - 5;
}
return arr;
}
//枚举O(n2)
int getMaxSubArray_1(intp arr, int low, int high)
{
int n = high - low + 1;//元素个数
int Sum = 0;
int maxSum = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
Sum += arr[j];
maxSum = max(Sum, maxSum);//每累加一个元素就比较一次,如果比较大就更新
}
Sum = 0;
}
return maxSum;
}
//递推O(n)
int getMaxSubArray_2(intp arr, int low, int high)
{
int n = high - low + 1;//元素个数
int Sum = arr[low];
int maxSum = 0;
for (int i = low + 1; i < n; i++)
{
if (Sum > 0) {
Sum += arr[i];
}
else {
Sum = arr[i];
}
maxSum = max(Sum, maxSum);
}
return maxSum;
}
//递推O(n)
/*返回一个数组arr
arr[0]:最大子段和
arr[1]:最大字段和的左端下标
arr[2]:最大子段和的右端下标
*/
intp getMaxSubArray_3(intp arr, int low, int high)
{
int n = high - low + 1;//元素个数
int Sum = arr[low];
int subArr[3];//记录最大子段和,左端下标和右端下标
memset(subArr, 0, sizeof(subArr));
for (int i = low + 1; i < n; i++)
{
if (Sum > 0) {
Sum += arr[i];
}
else {
Sum = arr[i];
subArr[1] = i;//丢弃就更新左端下标
}
//subArr[0] = max(Sum, subArr[0]);
if (Sum > subArr[0]) {
subArr[0] = Sum;
subArr[2] = i;
}
}
return subArr;
}
int main()
{
intp arr = randArray(LEN);
cout << "数组:";
for (int i = 0; i < LEN; i++)
cout << arr[i] << " ";
cout << endl;
intp res = getMaxSubArray_3(arr, 0, LEN - 1);
cout << "最大子段和:" << res[0] << "\n子段起点:" << res[1] << " 子段终点:" << res[2] << endl;
system("pause");
return 0;
}
算法学习--最大子段和
猜你喜欢
转载自blog.csdn.net/mu_mu_mu_mu_mu/article/details/104358081
今日推荐
周排行