一、题目描述:
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。
二、思路分析:
所有的算法题,都是可以通过暴力方式解决的。 先上循环思路:
- 将所有长度的数组通过双层循环,都截取出来保存在一个新数组中
- 通过循环数组中所有的截取项,加和对比找出其中的最大值并返回
var maxSubArray = function(nums) {
let max = '', allUnion = [];
const length = nums.length;
for (let i = 1; i <= length; i += 1) {
for (let j = 0; j < length; j += 1) {
if (j + i > length) break;
allUnion.push(nums.slice(j, j+i))
}
}
allUnion.forEach((x) => {
let sum = x.reduce((prev, next) => prev + next, 0)
if (sum > max || max === '') {
max = sum
}
})
return max;
}
上面代码看似没啥毛病,提交测试会报:内存溢出,多次循环面对大量数据免不了内存会爆了。
想不到其他的方法,那就看看题解吧。
官方解法
贪心算法
若当前指针所指元素之前的和小于0,则丢弃当前元素之前的序列 时间复杂度:O(n) 空间复杂度:O(1)
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;
};
动态规划
若前一个元素大于0,则将其加到当前元素上,最后取列表中最大元素得到最大子序和 时间复杂度:O(n) 空间复杂度:O(1)
var maxSubArray = function(nums) {
let pre = 0;
nums = nums.map((x) => {
if (pre > 0) {
x += pre
}
pre = x;
return x;
})
return Math.max(...nums);
}
四、总结:
看了题解,依然不能解惑
但至少弄我得先弄明白:空间复杂度、时间复杂度、动态规划、贪心算法,这四个概念都是啥意思
- 空间复杂度:一个算法在运行过程中临时占用存储空间大小的量度
- 时间复杂度:定性描述该算法的运行时间
- 动态规划:将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解
- 贪心算法:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。
题,第一遍看上去如果想不到其他解法就去看题解,不要浪费时间,有一个大概的印象就好不求一遍就会