做网站499,金溪做网站,自媒体平台注册账号,加强网站建设的请示给你一个整数数组 nums #xff0c;请你找出一个具有最大和的连续子数组#xff08;子数组最少包含一个元素#xff09;#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 解题思路
要注意最小值是整个前缀#xff0c;主要是cumsum然后按照买卖股票的思路做的请你找出一个具有最大和的连续子数组子数组最少包含一个元素返回其最大和。 子数组是数组中的一个连续部分。 解题思路
要注意最小值是整个前缀主要是cumsum然后按照买卖股票的思路做的但是边界处理很容易错可以以最开始几个边界来判定初始值这个方法挺好用的。
AC代码
class Solution:def maxSubArray(self, nums: List[int]) - int:minres 0res -infpre 0for index in range(len(nums)):pre nums[index]res max(res, pre - minres)minres min(minres, pre)return res官方思路
动态规划
注意动态规划的重点是以i结尾的最大子串只有加上结尾这个条件才能写递归式。
我们需要两个变量一个变量用来记录上一个递归结果其应该为单独上一个数或者上一个数加上前面一段。这里的变量逻辑和cumsum的前缀和逻辑是有区别的。
class Solution:def maxSubArray(self, nums: List[int]) - int:res nums[0]pre 0for n in nums:pre max(pre n, n)res max(res, pre)return res二分法
线段树的思想第一次看到需要维护四个变量分辨是非左端点最大值有点点最大值整区间值和区间内最大值这个思路其实像是多道二分法题目的合并了这种做法的好处在于可以存储任意区间的结果。如果需要多次输出结果这种方法的优势就比较明显了。
class Solution {
public:struct Status {int lSum, rSum, mSum, iSum;};Status pushUp(Status l, Status r) {int iSum l.iSum r.iSum;int lSum max(l.lSum, l.iSum r.lSum);int rSum max(r.rSum, r.iSum l.rSum);int mSum max(max(l.mSum, r.mSum), l.rSum r.lSum);return (Status) {lSum, rSum, mSum, iSum};};Status get(vectorint a, int l, int r) {if (l r) {return (Status) {a[l], a[l], a[l], a[l]};}int m (l r) 1;Status lSub get(a, l, m);Status rSub get(a, m 1, r);return pushUp(lSub, rSub);}int maxSubArray(vectorint nums) {return get(nums, 0, nums.size() - 1).mSum;}
};