✅作者简介:C/C++领域新星创作者,为C++和java奋斗中
✨个人社区:微凉秋意社区
🔥系列专栏:剑指offer精讲
📃推荐一款模拟面试、刷题神器👉注册免费刷题
🔥前言
今天给大家分享算法中的一个重要思想——动态规划。题目源自牛客网的 《剑指offer》 专栏,我将通过两个经理题目来给大家讲清楚动态规划思想,让大家面对这一类题目时有自己的解题思路。
首先我们要弄清楚题目的含义:什么是连续子数组?
搞清楚连续子数组后考虑该题的解法:
dp
中。max
作为最终的结果,并和数组dp中的元素不断对比,较大值将被赋值给max。图示助理解:
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
if(array.size()==1)
return *array.begin();
int dp[array.size()];
int max=array[0];
dp[0]=max;
for(int i=1;i<array.size();i++){
int temp=dp[i-1]+array[i];
dp[i] = temp>array[i]? temp:array[i];
if(dp[i]>max)
max=dp[i];
}
return max;
}
};
dp
的长度,初始化dp首元素和max的值为数组首元素的值max
,程序结束,问题解决。
该题是在连续子数组的和最大的基础上,返回该连续子数组,这里仍然使用动态规划来解题:
我们仍然要通过辅助数组dp
来记录连续子数组的最大值,并根据最大值来更新连续子数组的区间,最后将最长区间作为数组下标,将区间范围的元素全部插入到要返回的数组中。
具体做法:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型vector
* @return int整型vector
*/
vector<int> FindGreatestSumOfSubArray(vector<int>& array) {
// write code here
if(array.size()==1)
return array;
vector<int>res;
vector<int> dp(array.size(),0);
dp[0]=array[0];
int ans=dp[0];
//滑动区间
int left=0,right=0;
//最终的区间范围
int resl=0,resr=0;
for(int i=1;i<array.size();i++){
right++;
//状态转移:连续子数组的最大值
dp[i]=max(dp[i-1]+array[i], array[i]);
//区间新起点
if(dp[i-1]+array[i]<array[i])
left=right;
//更新最大值
if(dp[i]>= ans)
{
ans=dp[i];
resl=left;
resr=right;
}
}
//给res数组插入数据
for(int i=resl;i<=resr;i++)
res.push_back(array[i]);
return res;
}
};
dp
,最大值记为ans
且默认为数组首元素的值left=right
ans
比较:
ans
数组中并返回动态规划算法的基本思想是: