1186. 删除一次得到子数组最大和
题目地址(1186. 删除一次得到子数组最大和)
https://leetcode-cn.com/problems/maximum-subarray-sum-with-one-deletion/
题目描述
前置知识
数组
动态规划
公司
字节
思路
暴力法
符合知觉的做法是求出所有的情况,然后取出最大的。 我们只需要两层循环接口,外循环用于确定我们丢弃的元素,内循环用于计算 subArraySum。
空间换时间
上面的做法在 LC 上会 TLE, 因此我们需要换一种思路,既然超时了,我们是否可以从空间换时间的角度思考呢?我们可以分别从头尾遍历,建立两个 subArraySub 的数组 l 和 r。 其实这个不难想到,很多题目都用到了这个技巧。
具体做法:
一层遍历, 建立 l 数组,l[i]表示从左边开始的以 arr[i]结尾的 subArraySum 的最大值
这里以 xxx 结尾有两种情况,要么自身就是一个数,要么就是和前面结合构成一个子序列。只要取这两种情况的最大值即可(因为我们的目标是求最大值)
一层遍历, 建立 r 数组,r[i]表示从右边开始的以 arr[i]结尾的 subArraySum 的最大值
一层遍历, 计算 l[i - 1] + r[i + 1] 的最大值
l[i - 1] + r[i + 1]的含义就是删除 arr[i]的子数组最大值
上面的这个步骤得到了删除一个的子数组最大值。题目要求的是最多删除一个,因此还有一种不删除的情况。不删除的只需要在上面循环顺便计算一下即可。
动态规划
上面的算法虽然时间上有所改善,但是正如标题所说,空间复杂度是 O(n),有没有办法改进呢?答案是使用动态规划。
具体过程:
定义 max0,表示以 arr[i]结尾且一个都不漏的最大子数组和
定义 max1,表示以 arr[i]或者 arr[i - 1]结尾,可以漏一个的最大子数组和
遍历数组,更新 max1 和 max0(注意先更新 max1,因为 max1 用到了上一个 max0)
其中
max1 = max(max1 + arr[i], max0)
, 即删除 arr[i - 1]或者删除 arr[i]其中
max0 = max(max0 + arr[i], arr[i])
, 一个都不删除
复杂度分析
时间复杂度:$O(N)$
空间复杂度:$O(1)$
关键点解析
空间换时间
头尾双数组
动态规划
相关题目
最后更新于