本文答案参考自LeetCode官方题解。
题目描述
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
好家伙,我TM直接好家伙。[奸笑]
这题目花里胡哨的,难度竟然是简单!
【方法1】很明显:动态规划
直接贴官方给出的状态转移方程:
就是说:
- 开始时,将最大子序和 设置为 nums[ 0 ]
- 初始化 pre 变量记录 “前面最大子序和”
- 遍历数组(下标设为 i ),执行 pre = max( pre + nums[i] , nums[i] ),然后如果 pre 大过当前答案,则更新之。
其中似乎包含着一些数学知识,因为你看如果当前遍历到的数字 大于 pre,则直接 pre 取该数字。
哦,可能是因为程序是遍历进行的。
哎呀[抓狂][抓狂][抓狂],实在不懂就记住这行代码就可以了(上面的话就当我没说)
【方法2】分治
题目还提了个进阶要求:使用分治算法。
哇,我看了题解,没看懂[捂脸]
我尽量以我的理解大致讲一下思路:(注意程序是递归进行的)(可能会打错字母)
- 对数组进行二分直到一组只有一个数字
- 对 nums[ l , r ],分别计算:
- 以 nums[ l ] 为左端点的最大子段和,记为 lSum,lSum = max( 左子区间的 lSum , 左子区间的 iSum + 右子区间的 lSum)
- 以 nums[ r ] 为右端点的最大子段和,记为 rSum,rSum = max( 右子区间的 lSum , 左子区间的 rSum + 右子区间的 iSum)
- nums[ l , r ] 内的最大子段和,记为 mSum,mSum = max(左子区间的 mSum , 右子区间的 mSum , 左子区间的 rSum + 右子区间的 lSum)
- nums[ l , r ] 的区间和,记为 iSum,其值等于 nums[ l , r ] 的左子区间的区间和 加上 nums[ l , r ] 的右左子区间的区间和。nums[ l , r ] 只有一个数时,其区间和就是这个数。
- 答案就是整个 nums 的 mSum
原理神马的就不用管了︿( ̄︶ ̄)︿
字母 l 和 i 要看清,我的眼睛啊[捂脸]