这道题是典型的动态规划和分治法问题的考察,我初来乍到,压根不知道动态规划是啥当时,分治法最后都没咋看懂,准备以后回过头来好好再学学。
动态规划借助大佬们的题解我基本上已经看懂
原题链接如下:
53. 最大子数组和
解法0(无效解法,超时了,暴力解法):
class Solution {
public:
int maxSubArray(vector<int>& nums) {
//本次采用暴力解题
int sum = 0;
int res = nums[0];
for(int i=0;i<nums.size();i++){
int sum = 0;
for(int j = i;j<nums.size();j++){
sum += nums[j];
res = max(res,sum);
}
}
return res;
}
};
解法1(动态规划):
把原数组nums等长度的求出其对应的dp数组,dp数组(dp[i])也就是指以第 i个数结尾的「连续子数组的最大和」。
因此我们就只需要求出dp数组中每个位置的值,然后遍历返回dp数组中的最大值就可以了。
如何求dp[i]呢?这取决于nums[i]和dp[i-1]+nums[i]的大小了,如果dp[i-1]小于0,任何数加一个小于0的数都会越来越小,所以这时候还不如就让nums[i]单独一个人的值作为dp[i],如果dp[i-1]等于0,则nums[i] = dp[i-1]+nums[i](两个随便取哪个,无伤大雅),如果dp[i-1]大于0,那肯定dp[i-1]+nums[i]更大,所以我们此时的dp[i]就取dp[i-1]+nums[i],因此我们得到动态规划转移方程:
dp(i)=max{dp(i−1)+nums[i],nums[i]}
同时注意:由于每次的dp[i]的结果,最多只需要用到dp[i-1],不需要用到更往前的数据了,所以我们没必要造成空间浪费,用一个变量pre来维护对于每个当前dp[i]所对应的dp[i-1]的值,从而让空间复杂度降低到O(1)
代码如下:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int pre = 0;int Max = nums[0];//切记此处初始最大dp[i]的值必须弄成dp[0]别弄成变量的默认初始值0,不然有些边界情况会不满足,也即最大dp[i]也小于0的那种情况
for(int num:nums){
pre = max(pre+num,num);//这里每次pre的更新之后也就是dp[i]了,这个式子生效之前,pre就是dp[i-1],生效后pre的值就就代表dp[i]
Max = max(Max,pre);//Max变量是为了节省空间,没必要开辟一个dp[]数组,每次把更大的dp[i]的值存下来了往后比较就可以了,这个式子生效前,pre已经是dp[i]了,而Max的值是dp[0]...dp[i-1]中的最大的一个,用于和每次新生成的dp[i]进行比较
}
return Max;
};
执行用时:92 ms, 在所有 C++ 提交中击败了55.08%的用户
内存消耗:66.1 MB, 在所有 C++ 提交中击败了80.05%的用户
通过测试用例:209 / 209
解法2(贪心):
贪心的本质和动态规划是一样的,所以两者代码也基本雷同
贪心的基本思想就是若当前指针所指元素之前的元素之和小于0,则抛弃当前元素之前的数列,也就是用一个sum变量来维护,之前元素的sum小于0的话,任何一个数加上一个小于0的数字只会越加越小,不符合我们求最大的子序列值的思想,所以我们就可以抛弃之前的数列了,把sum的值临时赋值为当前这个元素,同时再维护一个Max变量来记录每次sum变化当中的最大值,总是和最新的sum进行比较,不断更新,从而到最后结束,能得出全过程中出现的最大的sum值,也就是我们Max变量的值
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int sum = 0;int Max = nums[0];
for(int num:nums){
if(sum<0){sum = num;}
else{
sum = sum+num;
}
Max = max(Max,sum);
}
return Max;
}
};
执行用时:92 ms, 在所有 C++ 提交中击败了55.08%的用户
内存消耗:66.1 MB, 在所有 C++ 提交中击败了85.81%的用户
通过测试用例:209 / 209
本题还有分治法的解法,本人水平有限,暂时看不懂,功力再高深一点之后再来填坑。
注:本人的LeetCode刷题记录系列有许多个人思考过程,看起来会很冗杂,仅供娱乐和记录而已,不喜勿喷,大家一起努力,一起进步。