Markdown在线编辑器 - www.MdEditor.com
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
暴力搜索的话n+n-1+n-2+..+1 种
以第i做起始,往后延续了几个元素 ,时间复杂度(n*n) 空间复杂度(1)保存一个最大值
例如: 1 2 情况有三1;1 2;2;
这个典型的大问题换小问题(分治法递归或者动态规划)
前n个元素连续子向量的最大和 = MAX(前n-1元素连续子向量最大和,以n结尾的所有情况)
如大问题 1 -2 10 ; 小问题 1 -2 小问题的解 最大值1 只取第一个元素;
根据小问题的状态,我们要搜索以10结尾的所有情况 (1 -2 10) (-2 10) (10);其结果和 小问题的解 1 去比较得到 最大为10(需要考虑n种情况)
以第i+1个元素结尾的最大连续子向量的值 = MAX(以第i个元素结尾的最大连续子向量的值, 以第i个元素结尾的最大连续子向量的值+第i+1个元素的值)
最后得到n个值,然后去最大的,就是结果
如1 -2 10,小问题以-2 结尾的最大值 (1 -2)=-1 ,大问题以10为结尾的最大值比较(以10的上上一个元素结尾的最大值-1+10) (10);结果为10
(仅两种情况且不需要保存一个之前选取的那些元素的数组)
class Solution { public: int Max(int a, int b) { return a > b ? a :b ; } int FindGreatestSumOfSubArray(vector<int> array) { int len = array.size(); if(len == 0) { return 0; } int result[len] ; // 每个问题(以第i元素结尾的最大子向量)的解 result[0] = array[0]; for(int i = 1;i < len; i++) { result[i] = Max(result[i-1] + array[i], array[i] ); } int max = result[0]; for(int i= 1; i < len; i++) { max = Max(max, result[i]); } return max; } };
原文:https://www.cnblogs.com/linxuesong/p/12197754.html