[路飞]_leetcode-53-最大子数组和

简介: leetcode-53-最大子数组和

网络异常,图片无法展示
|


「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战


[题目地址][B站地址]


给你一个整数数组 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


进阶: 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。


解题思路


首先说明本题不会讲解 分治法 解题,是因为要用到一种高级数据结构字段树,而且本题我们的题解是达到了最优解的(时间复杂度 O(n),空间复杂度 O(1))。


通常需要求解区间和的问题,大概率都需要借助前缀和数组解题。这里照顾不了解 前缀和数组 的小伙伴,我们来讲一下 前缀和数组。


前缀和数组


所谓前缀和数组,就是数组中的每一项,等于原数组中当前位置及之前元素的和值。


例如原数组为 [1,2,3,4], 前缀和数组为 [0,1,3,6,10]。 要注意的是前缀和数组中默认第一位是 0,所以前缀和数组的长度会比原数组长度 +1


为什么要有一个前置 0呢?


  1. 方便计算前缀和数组的第一项的值。因为我们求前缀和数组中当前项值的时候,只需要将前一项的值加上原数组前位置的元素值即可,那么为了原数组第一个元素计算的时候有前一项值,所以需要一个前置 0
  2. 方便计算区间和值。观察前缀和数组可以发现,后面的值减去前面的值,刚好等于原数组中该区间中的元素和值,即区间和值。那每一项减去最前面的 0,其实就是从原数组下标 0到当前位置的区间和值(这里要注意的是,因为有一个前置 0,所以前缀和数组中的下标等于原数组中的下标 +1)。


我们利用前缀和数组,可以很方便的求得某一段区间中元素的和值,也就是本题中的子数组和值。


所以我们可以遍历前缀和数组,同时记录前面区间中的最小值,然后用当前值减去前面区间的最小值,这样就得到了以当前位置为结尾,所能得到的最大的子数组和值。


然后尝试用这个结果更新结果值,最后就得到了数组中的最大子数组和。


要注意的是,在这个过程中,还需要尝试用当前位置的前缀和结果更新最小值,保证最小值保存的是已处理区间的最小值。


动画演示


网络异常,图片无法展示
|


代码实现


var maxSubArray = function(nums) {
  // 初始化之前区间的前缀和最小值为前置0
  let min = 0,
  // 第 0 前缀和结果为 前置0
  sum = 0,
  // 最大子数组和为负无穷
  max = -Infinity;
  // 遍历输入数组
  for(let i = 0;i<nums.length;i++){
    // 获取当前位置前缀和
    sum += nums[i]
    // 用当前位置前缀和减去前面区间前缀和的最小值
    // 就得到了以当前位置为结尾所能得到的最大子数组和
    // 用这个结果尝试更新结果值
    max = Math.max(max,sum-min)
    // 用当前位置前缀和尝试更新最小值
    min = Math.min(min,sum)
  }
  return max;
};
复制代码


至此我们就完成了 leetcode-53-最大子数组和


如有任何问题或建议,欢迎留言讨论!

相关文章
|
2月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
48 0
|
4月前
|
算法
LeetCode第53题最大子数组和
LeetCode第53题"最大子数组和"的解题方法,利用动态规划思想,通过一次遍历数组,维护到当前元素为止的最大子数组和,有效避免了复杂度更高的暴力解法。
LeetCode第53题最大子数组和
|
2月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
26 4
|
2月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
26 0
Leetcode第三十三题(搜索旋转排序数组)
|
2月前
|
算法 C++
Leetcode第53题(最大子数组和)
这篇文章介绍了LeetCode第53题“最大子数组和”的动态规划解法,提供了详细的状态转移方程和C++代码实现,并讨论了其他算法如贪心、分治、改进动态规划和分块累计法。
76 0
|
2月前
|
C++
【LeetCode 12】349.两个数组的交集
【LeetCode 12】349.两个数组的交集
23 0
|
4月前
|
算法
LeetCode第81题搜索旋转排序数组 II
文章讲解了LeetCode第81题"搜索旋转排序数组 II"的解法,通过二分查找算法并加入去重逻辑来解决在旋转且含有重复元素的数组中搜索特定值的问题。
LeetCode第81题搜索旋转排序数组 II
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
64 6
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
128 2