「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」
53. 最大子数组和
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。
示例 1:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入: nums = [1]
输出: 1
示例 3:
输入: nums = [5,4,-1,7,8]
输出: 23
提示:
1 <= nums.length <= 105-104 <= nums[i] <= 104
暴力求解
思路
直接双循环,分别求出从i到j的所有结果,每次比较i到j的和与最大值max的值,重新赋值max 最后直接返回max即可
具体实现:
- 双循环外层i开始,内层j=i开始;
*我们这里使用滚动数组的方式,用一个curr记录下上次计算的结果,接下来j++的时候,curr = curr + nums[i]
- 比较max与curr的大小
最后返回max
时间复杂度n2超时
var maxSubArray = function (nums) {
var len = nums.length;
var curr = null;
var max = null;
for (var i = 0; i < len; i++) {
for (var j = i; j < len; j++) {
if (i === j) {
curr = nums[i]
} else {
curr = curr + nums[j]
}
// 给max赋值
if (max !== null) {
max = Math.max(curr, max)
} else {
max = curr
}
}
}
return max;
};
贪心
思路 贪心的核心思想是:如果当前元素之前的元素和为负数,那么就可以直接丢弃了,因为任何数与负数相加都只会更小。
具体实现:
- 直接定义当前值curr = nums[0],max=curr
- 从i=1开始遍历nums,判断curr(当前元素之前的元素和)的值
- curr小于0为负数,直接舍弃curr,curr从新赋值为当前值
- curr大于0,那么正常累加
- 比较curr和max的大小,保留较大值 最后直接返回max即可
var maxSubArray = function (nums) {
// 贪心
var len = nums.length;
var curr = nums[0];
var max = curr;
for (var i = 1; i < len; i++) {
if(curr<0){
curr = nums[i]
}else{
curr = curr + nums[i]
}
max = Math.max(curr,max)
}
return max;
};
动态规划
思路 动态规划的思路和贪心类似,如果之前的元素和为负数则当前值不做任何处理,也是舍弃负数的结果,如果前一个元素值大于0才会加在当前元素上
具体实现:
- 直接从i = 1开始遍历nums,判断nums的前一位i-1的值
- 如果i-1位负数则当前i无需处理
- 如果i-1位正数,则当前值为i-1加上nums[i]的值 最后我们在整个nums数组中取最大值
返回最大值即可
var maxSubArray = function (nums) {
// 动态规划
var len = nums.length;
for (var i = 1; i < len; i++) {
if(nums[i-1]>0){
nums[i] = nums[i-1] + nums[i]
}
}
return Math.max(...nums);
};