给定一段序列输出最大子数组和以及最大子数组的开始,结尾索引值

1、思路:

1.贪心:若当前指针所指元素之前的和小于0,则丢弃当前元素之前的序列
		遍历过程中需要维护当前和,之前和,最大和,最大和的前后边界以及当前值
		时间复杂度:o(n),只遍历了一次数组
		空间复杂度:o(1),只使用了常数空间
2.动态规划:若前一个元素大于0,则将其加到当前元素上
		过程中记录最大元素,以及最大元素所在位置即可
		时间复杂度:O(n)
		空间复杂度:O(1)
		寻找最大子数组起始边界:从最大元素所在位置向前回溯,直到元素值小于0。

2、测试数据:

输入:
	4
	4
	-1 2 3 -4              
	5
    -1 2 -5 3 -4           
	5
    -1 20 -5 30 -4         
	5
    -2 -3 -5 -1 -9        
输出:
	找到的最大子数组为:[2,3],sum:5
	找到的最大子数组为:[3],sum:3
	找到的最大子数组为:[20,-5,30],sum:45
	找到的最大子数组为:[-1],sum:-1

3、关键函数:

(1)贪心算法实现代码:

void greedy(int n) {
	int before_sum = -1;
	for(int i = 0; i < n; i++) {
		if (before_sum < 0) {
			before_sum = arr[i];
			beginindex = i; //更新起始求和位置
		}
		else {
			before_sum += arr[i];
		}
		if (before_sum > sum) {
			endindex = i;
			sum = before_sum;
		}
	}
}

(2)动态规划实现代码:

void dynamic_programming(int n) {
	if (n == 1) {
		return;
	}
	//以下过程只修改endindex
	for (int i = 1; i < n-1; i++) {
		if (arr[i - 1] > 0) {
			arr[i] += arr[i - 1];
		}
		if (arr[i] > sum) {
			sum = arr[i];
			endindex = i;
		}
	}
	//寻找beginindex;
	beginindex = endindex;
	while (beginindex>=1)
	{
		if (arr[beginindex - 1] > 0) {
			beginindex--;
		}
		else {
			break;
		}
	}
}

(3)完整代码(含主函数测试和输出函数):

#include
using namespace std;
int* arr;
int sum = 0, beginindex = 0, endindex = 0;
void greedy(int n) {
	int before_sum = -1;
	for(int i = 0; i < n; i++) {
		if (before_sum < 0) {
			before_sum = arr[i];
			beginindex = i; //更新起始求和位置
		}
		else {
			before_sum += arr[i];
		}
		if (before_sum > sum) {
			endindex = i;
			sum = before_sum;
		}
	}
}
void dynamic_programming(int n) {
	if (n == 1) {
		return;
	}
	//以下过程只修改endindex
	for (int i = 1; i < n-1; i++) {
		if (arr[i - 1] > 0) {
			arr[i] += arr[i - 1];
		}
		if (arr[i] > sum) {
			sum = arr[i];
			endindex = i;
		}
	}
	//寻找beginindex;
	beginindex = endindex;
	while (beginindex>=1)
	{
		if (arr[beginindex - 1] > 0) {
			beginindex--;
		}
		else {
			break;
		}
	}
}
void print() {
	cout << "找到的最大子数组为:[";
	for (int i = beginindex; i > m;
	for (int q = 0; q < m; q++) {
		cout << "请输入序列的长度:";
		cin >> n;
		if (n <= 0) {
			cout << "序列长度需要大于0。" << endl;
			continue;
		}
		arr = new int[n];
		cout << "请依次输入元素:";
		for (int i = 0; i < n; i++) {
			cin >> arr[i];
		}
		sum = arr[0];
		greedy(n);
		cout << "(1)贪心算法计算的结果:" << endl;
		print();
		sum = arr[0];
		dynamic_programming(n);
		cout << "(2)动态规划计算的结果为:" << endl;
		print();
	}
	return 0;
}

你可能感兴趣的:(算法,leetcode,算法,职场和发展)