昨天终于是把动态规划算法的文章给写完了
现在是浑身轻松
虽然前几天被折磨的死去活来的
但看到自己写的文章
还是觉得十分满足
53-最大子序和
给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
思路:
这一题是很典型的动态规划题目了,动态规划是算法题中非常爱考的一个知识点。如果你能把它的套路学会了,那说简单也简单,如果你完全是迷迷糊糊的,那说难也是很难了。昨天刚好写了一篇关于求解动态规划算法的文章,里面详细介绍了关于动态规划解题步骤的东西,大家可以先看看。
程小新同学:动态规划方法心得zhuanlan.zhihu.com看完这篇文章之后,相信大家应该会有个大致的印象,具体的细节这儿我就不过费口舌了。本题我就其状态转移方程好好说说,文字公式较多,我就直接上图了。
但是整个数组的最大值不是直接通过标记列表flag_list得到的,需要另外设置一个max_num数作比较得到,具体的可见下面代码。
代码如下:
class Solution(object):
# 本题采用动态规划的方法
# 本题转移方程的情况稍多,需要分类讨论;主要是数组中出现0的情况;以及连续负数前后关联的情况需要好好考虑
# 主要的转移方程就是:如果当前位置的数<0,则当前的标记列表元素为0;如果当前位置的数>0,则当前位置的标记列表元素为
# 上一个非负数对应的标记列表元素+上一个非负数右面所有负数以及当前index-1位置的整数的和与当前index-1位置元素的最大值
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 0:
return 0
# 定义一标记列表,长度为len(nums)+1,用来记录每个元素对应的连续元素的最大值
flag_list = [0]*(len(nums)+1)
flag_list[0] = 0
# 该值用来记录flag_matrix列表中的最大值
max_num = nums[0]
start = 0
for index in range(1, len(nums)+1):
if nums[index-1] <= 0:
max_num = max(max_num, nums[index-1])
start += 1
elif nums[index-1] > 0:
# 获取当前index位置的上一个非负数的下标
last_index = index - start-1
# 获取上一个非负数右面所有负数以及当前index-1位置的整数的和
all_sum = flag_list[last_index] + sum(nums[last_index: index])
flag_list[index] = max(all_sum, nums[index-1])
max_num = max(max_num, flag_list[index])
start = 0
# 这一步其实也很关键,因为我们的nums数组是去0数组的,所以如果最后得到的最大数为负数,而刚好nums数组里又刚好有0
# 则最大数要更换为0
if len(nums) < len(nums) and max_num < 0:
max_num = 0
return max_num
if __name__ == "__main__":
nums = [1, 0, 0, 0, 3]
max_length = Solution().maxSubArray(nums)
print(max_length)
执行效率属于中等吧,在50%左右。
当然我给的方法是严格按照我总结的程式三步法来的,网上有很多大佬给出了更加简洁的版本,但是这个太考验算法功底了。尤其是对我这种菜鸟来说,虽然一看就懂,但你要让我自己去写,我估计想个十天半个月都想不到,火候还没到家啊!所以我建议还在上路的读者可以先用我的方法来,这个比较保稳。当然了,我还是想分享一下一个更简洁的版本,作为启发吧。
代码如下:
class Solution:
# 本题是采用比较典型的动态规划算法解决的
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) <= 1:
return sum(nums)
temp = 0
max_num = nums[0]
for index in nums:
if temp < 0:
temp = index
else:
temp += index
max_num = max(max_num, temp)
return max_num
if __name__ == "__main__":
nums = [-2, 1, -3, -5]
final_list = Solution().maxSubArray(nums)
print(final_list)
执行效率在80%左右。