C语言力扣刷题13------最大子数组和[线性动态规划]
一、博客声明
找工作逃不过刷题,为了更好的督促自己学习以及理解力扣大佬们的解题思路,开辟这个系列来记录。代码可能不是自己写的,不求方法最好,只求更多地理解大佬们的解题思路。
二、题目描述
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1]
输出:1
示例 3:
输入:nums = [5,4,-1,7,8]
输出:23
提示:
1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
三、解题思路
1、思路说明
这个题目只考虑找到众多子数组中求和的最大值即可,其实不用关注这个子数组的起点和终点在什么位置。我们只需要知道到数组第i
个元素时,求和的最大值就可以。
举个例子:
-
[-2, 1]
- 到第
0
个元素时,求和的最大值为-2
,用一个变量total
记录下来,total = -2
; - 到第
1
个元素时,就需要看它与前面之和加起来total + nums[1]
和它自己本身nums[1]
大,然后更新total = fmax(total + nums[1], nums[1])
,其中total
就是到当前位置,前面能累加到的最大值。
- 到第
-
[-2, 1, -3]
- 到第
0
个元素时,求和的最大值为-2
,用一个变量total
记录下来,total = -2
; - 到第
1
个元素时,就需要看它与前面之和加起来total + nums[1]
和它自己本身nums[1]
大,然后更新total = fmax(total + nums[1], nums[1])
,其中total
就是到当前位置,前面能累加到的最大值,total = 1
。 - 到第
2
个元素时,就需要看它与前面之和加起来(-2
)和它自己本身(-3
)大,因此更新后的total = -2
。
- 到第
-
[-2, 1, -3, 4]
- 到第
0
个元素时,求和的最大值为-2
,用一个变量total
记录下来,total = -2
; - 到第
1
个元素时,就需要看它与前面之和加起来total + nums[1]
和它自己本身nums[1]
大,然后更新total = fmax(total + nums[1], nums[1])
,其中total
就是到当前位置,前面能累加到的最大值,total = 1
。 - 到第
2
个元素时,就需要看它与前面之和加起来(-2
)和它自己本身(-3
)大,因此更新后的total = -2
。 - 到第
3
个元素时,就需要看它与前面之和加起来(2
)和它自己本身(4
)大,因此更新后的total = 4
。
- 到第
-
[-2, 1, -3, 4, -1]
- 到第
0
个元素时,求和的最大值为-2
,用一个变量total
记录下来,total = -2
; - 到第
1
个元素时,就需要看它与前面之和加起来total + nums[1]
和它自己本身nums[1]
大,然后更新total = fmax(total + nums[1], nums[1])
,其中total
就是到当前位置,前面能累加到的最大值,total = 1
。 - 到第
2
个元素时,就需要看它与前面之和加起来(-2
)和它自己本身(-3
)大,因此更新后的total = -2
。 - 到第
3
个元素时,就需要看它与前面之和加起来(2
)和它自己本身(4
)大,因此更新后的total = 4
。 - 到第
3
个元素时,就需要看它与前面之和加起来(3
)和它自己本身(-1
)大,因此更新后的total = 3
。
- 到第
从上面就可以知道,total可以保存到第i个位置时能累加到的最大值,都不用管他是从哪个位置开始累加的。因此我们只需要找到total的最大值就可以了。
解释起来非常的牵强,还是得多练
四、解题代码(附注释)
c
int maxSubArray(int* nums, int numsSize){
int ret = nums[0], total = 0;
for(int i =0; i < numsSize; i++){
total = fmax(total + nums[i], nums[i]); //total就是dp,代表第i个元素累加的最大值
ret = fmax(ret, total);
}
return ret;
}