【LintCode】41. 最大子数组
要求时间复杂度为O(n);
设F[n]为以下标为n的nums[n]结尾的连续子序列的最大和,那么显然F[0]=nums[0];
所以根据动态规划的思想有:
F[n] = max(F[n-1]+nums[n], nums[n]);
所以写出动态规划的程序:(动态规划的核心体现在编程上就是反复的读取数据、计算数据、存储数据)
int maxSubArray(vector<int> &nums){
//Dynamic Programming
int total = nums.size();
int *a = new int[total];
a[0] = nums[0]; // 设置初始值
for(int i=1;i<total;i++){ // 读取数据 计算数据 存储数据
a[i] = max(nums[i],a[i-1]+nums[i]);
}
// 整个循环结束之后 找出a[]数组中的最大值就是我们要求的值
int ret = INT_MIN;
for(int i=0;i<total;i++){
if(ret<a[i]){
ret = a[i];
}
}
delete [] a;
return ret;
}
鉴于我们只需要求出那个最大值就可以了,所以我们不用开辟一片数组,因为F[n]只和F[n-1]和nums[n]有关系,所以只需要几个变量来存储当前所需要计算的值和计算的结果就可以了,具体代码如下:
int maxSubArray(vector<int> &nums) {
int total = nums.size();
int ret = nums[0];
int front = nums[0];
int cur = 0;
for(int i=1;i<total;i++){
//cur = max(nums[i],front+nums[i]);
if(nums[i]>front+nums[i]){
cur = nums[i];
}else{
cur = front+nums[i];
}
front = cur;
if(cur>ret){
ret = cur;
}
}
return ret;
}
这个题目使我真正理解到了动态规划的核心,也让我体会到了动态规划的优越性。