【小学数学向】最大子数组和
正规解法
状态转移方程 f(i)=max{f(i−1)+nums[i],nums[i]}
var maxSubArray = function(nums) {
let pre = 0, maxAns = nums[0];
nums.forEach((x) => {
pre = Math.max(pre + x, x);
maxAns = Math.max(maxAns, pre);
});
return maxAns;
};
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/maximum-subarray/solution/zui-da-zi-xu-he-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
递归算以第 i 个数结尾的「连续子数组的最大和」然后在计算的过程中,求出最大值
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function(nums) {
let max = -Infinity
let dp = function(i) {
let a = nums[0]
if (i !== 0)
a = Math.max(nums[i], dp(i - 1) + nums[i])
max = Math.max(a,max)
return a
}
dp(nums.length - 1)
return max
};
蠢蠢的二维dp
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function(nums) {
let memo = Array.from(new Array(nums.length + 1),
x => Array(nums.length).fill(null))
memo[1] = nums
let max = -Infinity
/** @param {number} i start position
@param {number} j length*/
let dp = function(i,j) {
let a = memo[j][i]
if (memo[j][i] === null)
a = memo[j][i] = Math.max(dp(i,j - 1) + nums[i + j - 1],
dp(i + 1,j - 1) + nums[i])
max = Math.max(a,max)
return a
}
dp(0, nums.length)
return max
};
改成递推 + 滚动数组,还是超时了,这其中有一些边界问题,很值得细细品味(比如j从0开始)
/**
* @param {number[]} nums
* @return {number}
*/
var maxSubArray = function(nums) {
let memo1 = Array(nums.length).fill(0)
let memo2 = []
let max = -Infinity
/** @param {number} i start location
@param {number} j subarr.length */
for (let j = 1;j <= nums.length;j++) {
// 5个数,最后一个i应该是,5 - 2 + 1(位序)
// 转换成数组下标就是len - j了
for (let i = 0;i <= nums.length - j;i++)
max = Math.max(memo2[i] = memo1[i] + nums[i + j - 1],max)
memo1 = memo2;memo2 = []
}
return max
};