题目
53.最大子序列和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
动态规划思路
示例输入输出
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
分析
用一个数组dp[i]
来存储当前连续子数组的最大和,循环遍历原数组nums[i]
的时候,检验一下dp[i-1]
是否大于0,如果dp[i-1]>0
,则dp[i]=dp[i-1]+nums[i]
,否则dp[i]=nums[i]
,最后遍历dp
数组,找出最大元素即可。
一开始没有想清楚的地方是为什么要判断dp[i-1]的正负,而不是判断nums[i]的正负。记录一下:题目中要求的是连续子数组,dp存储的是以nums[i]为结尾的最大子序列和,因此必然要把nums[i]包含在内(如果实际最大的和中不包含nums[i],那么已经在前面的元素中记录过了不需要在此步考虑),所以只需要考虑nums[i]要不要加上前面的。
代码
方法一
int maxSubArray(vector<int>& nums) {
int n=nums.size();
vector<int> res(n,0);
//注意这一步,务必进行初始化否则会报错
res[0]=nums[0];
int mmax=nums[0];
for(int i=1;i<nums.size();i++){
res[i]=(res[i-1]>0?res[i-1]+nums[i]:nums[i]);
mmax= max (res[i],mmax);
}
return mmax;
}
方法二:对空间进行优化
int maxSubArray(vector<int>& nums) {
int res=nums[0];
int mmax=nums[0];
for(int i=1;i<nums.size();i++){
res = (res>0?res+nums[i]:nums[i]);
mmax= max (res,mmax);
}
return mmax;
}
题目
爬楼梯
这道题我感觉跟斐波那契是一样的,但没理解为什么评论区说是动态规划。。总之就是递归或者迭代。
int climbStairs(int n) {
//递归超时
/*
if(n==1) return 1;
if(n==0) return 1;
return climbStairs(n-1)+climbStairs(n-2);
*/
if(n==1) return 1;
if(n==2) return 2;
int n1=1;int n2=2;int res;
for(int i=3;i<=n;i++){
res = n1+n2;
n1=n2;
n2=res;
}
return res;
}