LeetCode 热题 100 之 53. 最大子数组和
题目
给你一个整数数组 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
思路
暴力解法:超时
先计算前缀和再两层循环找到最大值
动态规划:
题目要求我们找出连续子数组的最大和,并没有要求得。到是最大的是哪一个,因此通常可以用动态规划解决。
动态规划的思想通过解决了一个一个简单的问题,进而把简单的问题的解组成了复杂的问题的解。
对问题进行分解,要找到连续子数组的最大和,那么对给定的每个位置上的数字进行分析,比如计算[-2,1,-3,4,-1,2,1,-5,4]的最大子数组和,分解成9个子问题,1:以-2为结尾的子数组其和最大值为多少?2:以1为结尾的最大子数组和为多少,3:以-3为结果的最大子数组和为多少?……
子问题1:以-2结尾的子数组为[-2],因此的答案是-2。z(自身nums[0])
子问题2:以1结尾的子数组为[-2,1],[1]可以发现的答案是1。(自身 nums[1])
子问题3,以-3即为的子数组为[-2,1,-3],[1,-3],[-3],可以发现其答案是-2(前一个问题的答案+ nums[2])
……
定义子问题
dp[i]:表示以 nums[i] 结尾的连续子数组的最大和。由dp[i]定义可知nums[i]一定会选取。
假设数组 nums 的值全都严格大于 0,那么一定有 dp[i] = dp[i - 1] + nums[i]。但是dp[i-1]可能为负数。
以num[i-1]结尾(即dp[i-1])的最大子数组是否能加入到以nums[i]结尾的连续子数组,要看其dp[i-1]的值,如果dp[i-1]<=0,那么以nums[i]结尾的连续子数组肯定不要包含以nums[i-1]结尾的连续子数组,这样构成的以nums[i]结尾的连续子数组和才不会取得更低(实际上dp[i-1]<=0,则以nums[i]的连续子数组的最大和取的就是nums[i]),如果dp[i-1]>0 ,那么可以把 nums[i] 直接接在 dp[i - 1] 表示的那个数组的后面,得到和更大的连续子数组。
代码
暴力解法:超时
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
n = len(nums)
temp =0
max=nums[0]
pre = [0]
sum = 0
for i in range(n):
sum+=nums[i]
pre.append(sum)
for i in range(n+1):
for j in range(0,i):
if(pre[i]-pre[j]>max):
max = pre[i]-pre[j]
return max
动态规划
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
n = len(nums)
if(n ==0):
return 0
dp = [0 for i in range(n)]
dp[0]=nums[0]
for i in range(1,n):
if (dp[i-1]>0):
dp[i]=dp[i-1]+nums[i]
else:
dp[i]=nums[i]
return max(dp)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了