问题概述
题目:53.最大子序和(LeetCode)
问题描述:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
输入:
给定数组元素个数n,以及n个元素值nums[i];
1 <= n <= 3 * 10^4
-10^5 <= nums[i] <= 10^5
输出:
最大子序和值
样例输入:
9
-2 1 -3 4 -1 2 1 -5 4
样例输出:
6
1. 问题分析
1.1 算法核心
本题是一道简单的动态规划算法题,动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。
1.2 算法分析
分析算法本身,现在我们要对一个有n个元素的整形数组nums求它的最大子序和值,假设f(i)代表以第i个数结尾的连续子数组的最大和,也就是第i个元素前的最大子序和。那么我们本题所要求的的答案就是:
在0-n-1(nums数组下标)范围内,最大的f(i)值;
因此我们只需要求出所有的f(i)值,然后返回最大的即可,那怎么求f(i)呢,这里展示动态规划的设计思路。
对于当前的f(i)来说,要么最大子序和是f(i-1) + nums[i]要么是自己本身nums[i],若是前i - 1个元素的最大子序和值还没有我第i个元素本身要大,那就抛弃前i - 1个元素,最大子序和等于第i个元素的值,得到表达式:f(i) = max{ f(i - 1) + nums[i], nums[i] };
那么我们声明一个pre变量来保存f(i - 1)就可以开始动态规划了。
2. 解决方案
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
/*
算法题目:53.最大子序和(LeetCode)
问题描述:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
输入:
给定数组元素个数n,以及n个元素值nums[i];
1 <= n <= 3 * 10^4
-10^5 <= nums[i] <= 10^5
输出:
最大子序和值
样例输入:
9
-2 1 -3 4 -1 2 1 -5 4
样例输出:
6
*/
int maxSubArray(vector<int>& nums);
int main(void)
{
int n, t;
vector<int> nums;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> t;
nums.push_back(t);
}
t = maxSubArray(nums);
cout << t << endl;
return 0;
}
int maxSubArray(vector<int>& nums)
{
int pre = 0, maxAns = nums[0];
for (const auto &x : nums)
{
pre = max(pre + x, x);
maxAns = max(maxAns, pre);
}
return maxAns;
}
3. 资源分享
旗木白哉のGitHub:
https://github.com/YangMengHeng
GitHub/Gitee源代码下载地址:
GitHub
https://github.com/YangMengHeng/myCode/tree/master/VSCode
https://github.com/YangMengHeng/myCode/tree/master/Java
Gitee
https://gitee.com/QMBZ/myCode/tree/master/VSCode
https://gitee.com/QMBZ/myCode/tree/master/Java
旗木白哉のblog源代码下载地址:
https://github.com/YangMengHeng/myCode/tree/master/%E6%97%97%E6%9C%A8%E7%99%BD%E5%93%89%E3%81%AEblog
https://gitee.com/QMBZ/myCode/tree/master/%E6%97%97%E6%9C%A8%E7%99%BD%E5%93%89%E3%81%AEblog