算法学习--最大子段和

//求一个数组的最大子段和
//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;
}
发布了25 篇原创文章 · 获赞 17 · 访问量 720

猜你喜欢

转载自blog.csdn.net/mu_mu_mu_mu_mu/article/details/104358081