原题地址: https://leetcode-cn.com/probl...
repo地址: https://github.com/pigpigever...
原文连接: http://www.javashuo.com/article/p-pkjiqubc-bh.html
给定一个整数数组 nums ,找到一个具备最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
这道题其实能够直接从题目提供的输入输出着手,对于输入为:[ -2, 1, -3, 4, -1, 2, 1, -5, 4 ]
的详细分析以下:javascript
[ -2 ]
的状况,那么结果显然是 -2
[ -2, 1 ]
的状况,最程序化的比较固然是比较这三个结果的大小:-2
、 -2 + 1
和 1
的大小对不对?由于从黑盒的角度上看咱们并不能一眼看出结果,不过结果固然是 1
[ -2, 1, -3 ]
的状况,咱们依然像一个机器人同样列出来:-2
、 -2 + 1
、 -2 + 1 + (-3)
、 1
、 1 + (-3)
和 -3
,可是咱们注意到刚才列出来的状况里面:-2
、 -2 + 1
和 1
都是 [ -2, 1 ]
里的状况,因此结论就是:求 [ -2, 1, -3 ]
的 「最大子序列和」 也就是求 [ -2, 1 ]
的 「最大子序列和」和 -3
之间的「最大子序列和」根据上面推导过程当中的结论咱们能够把它概括成一个状态转移方程,定义以下: 前端
定义一个序列 S[i]
,存在元素为 A[i]
,当 i = 0
时,S[0] = A[0]
;
当 i > 0
时, S[i] = max{S[i - 1] + A[i], A[i]}
java
/** * @param {number[]} nums * @return {number} */ var maxSubArray = function(nums) { const dp = [nums[0]], len = nums.length let max = dp[0] for (let i = 1; i < len; i++) { dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]) max = Math.max(dp[i], max) } return max };
不过这里的空间复杂度能够优化下👇git
/** * @param {number[]} nums * @return {number} */ var maxSubArray = function(nums) { let ans = nums[0], max = nums[0] for (let i = 1; i < nums.length; i++) { ans = Math.max(nums[i] + ans, nums[i]) nums[i] = ans max = Math.max(ans, max) } return max };
一直在 LeetCode 上刷题,以前还加入了组织,有兴趣加入一块儿学习的同窗能够在下方留言或者关注个人微信公众号「tony老师的前端补习班」并在后台留言,能够进群跟大佬们一块儿学习。github