算法-最大子序和

问题概述


题目: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


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值