LeetCode53.最大子序和
作者:互联网
原题链接:https://leetcode-cn.com/problems/maximum-subarray/
题目简述:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
题解:
最长的子序列,那考虑的一般情况就是由一串正数和负数构成的数组且相加大于0。
贪心解法:
将首位暂记为最大值,从首位开始依次相加,若结果大于0则保留该结果并参与下一次相加,结果小于0则舍弃该结果,并从下一位开始从0相加。其中每次的结果都与最大值比较并保存其中较大的值。
注:因题干中说明子数组最少包含一个元素故不做过多判断。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max_value = nums[0];
int tmp = 0;
for (int value : nums) {
tmp += value;
if (tmp > max_value ) {
max_value = tmp;
}
if (tmp < 0) {
tmp = 0;
}
}
return max_value ;
}
};
动态规划解法:
该问题是求最大子序和,而该子序必然是以数组中某个数字结尾的,所以我们可以将该问题分解为求数组中所有数字结尾的连续子序列的最大和,其中最大的值为答案。
假设该数组有n个数字,那么假设f(n)的意思是以第n个数字结尾的连续子序列的最大和。那么求该数组的最大子序和也就是找到在f(1)到f(n)中最大的值。
那么由我们自己的定义可以推出方程(nums为数组):
f(n) = max(f(n-1) + nums[n], nums[n])
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max_value = nums[0];
int tmp = 0;
for (int value : nums) {
tmp = max(value, tmp + value);
max_value = max(max_value, tmp);
}
return max_value;
}
};
分治解法:
将数组分为左右两部分,那么该数组的最大子序和要么在左半边产生(左边的最大子序和),要么在右半边产生(右边的最大子序和),要么是穿过中间的间隔(左边数组的以最右侧数字为端点的最大连续子序和+右边数组的以最左侧数字为端点的最大连续子序和)。问题就拆解了。
标签:tmp,最大,nums,max,LeetCode53,value,数组,子序 来源: https://blog.csdn.net/an_a_an_apple/article/details/117450391