LeetCode 题解工作台
最大化子数组的总成本
给你一个长度为 n 的整数数组 nums 。 子数组 nums[l..r] (其中 0 )的 成本 定义为: cost(l, r) = nums[l] - nums[l + 1] + ... + nums[r] * (−1) r − l 你的任务是将 nums 分割成若干子数组,使得所有子数组的成本…
2
题型
5
代码语言
3
相关题
当前训练重点
中等 · 状态·转移·动态规划
答案摘要
根据题目描述,如果当前数没取反,那么下一个可以取反,也可以不取反;如果当前数取反了,那么下一个只能不取反。 因此,我们定义一个函数 $\textit{dfs}(i, j)$,表示从第 个数开始,第 个数是否能取反,其中 表示第 个数是否取反。如果 $j = 0$,表示第 个数不能取反,否则可以取反。答案为 $\textit{dfs}(0, 0)$。
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路
题目描述
给你一个长度为 n 的整数数组 nums。
子数组 nums[l..r](其中 0 <= l <= r < n)的 成本 定义为:
cost(l, r) = nums[l] - nums[l + 1] + ... + nums[r] * (−1)r − l
你的任务是将 nums 分割成若干子数组,使得所有子数组的成本之和 最大化,并确保每个元素 正好 属于一个子数组。
具体来说,如果 nums 被分割成 k 个子数组,且分割点为索引 i1, i2, ..., ik − 1(其中 0 <= i1 < i2 < ... < ik - 1 < n - 1),则总成本为:
cost(0, i1) + cost(i1 + 1, i2) + ... + cost(ik − 1 + 1, n − 1)
返回在最优分割方式下的子数组成本之和的最大值。
注意:如果 nums 没有被分割,即 k = 1,则总成本即为 cost(0, n - 1)。
示例 1:
输入: nums = [1,-2,3,4]
输出: 10
解释:
一种总成本最大化的方法是将 [1, -2, 3, 4] 分割成子数组 [1, -2, 3] 和 [4]。总成本为 (1 + 2 + 3) + 4 = 10。
示例 2:
输入: nums = [1,-1,1,-1]
输出: 4
解释:
一种总成本最大化的方法是将 [1, -1, 1, -1] 分割成子数组 [1, -1] 和 [1, -1]。总成本为 (1 + 1) + (1 + 1) = 4。
示例 3:
输入: nums = [0]
输出: 0
解释:
无法进一步分割数组,因此答案为 0。
示例 4:
输入: nums = [1,-1]
输出: 2
解释:
选择整个数组,总成本为 1 + 1 = 2,这是可能的最大成本。
提示:
1 <= nums.length <= 105-109 <= nums[i] <= 109
解题思路
方法一:记忆化搜索
根据题目描述,如果当前数没取反,那么下一个可以取反,也可以不取反;如果当前数取反了,那么下一个只能不取反。
因此,我们定义一个函数 ,表示从第 个数开始,第 个数是否能取反,其中 表示第 个数是否取反。如果 ,表示第 个数不能取反,否则可以取反。答案为 。
函数 的执行过程如下:
- 如果 ,表示已经遍历完了数组,返回 ;
- 否则,第 个数可以不取反,此时答案为 ;如果 ,表示第 个数可以取反,此时答案为 。我们取两者的最大值即可。
为了避免重复计算,我们可以使用记忆化搜索,将已经计算过的结果保存起来。
时间复杂度 ,空间复杂度 。其中 是数组 的长度。
class Solution:
def maximumTotalCost(self, nums: List[int]) -> int:
@cache
def dfs(i: int, j: int) -> int:
if i >= len(nums):
return 0
ans = nums[i] + dfs(i + 1, 1)
if j == 1:
ans = max(ans, -nums[i] + dfs(i + 1, 0))
return ans
return dfs(0, 0)
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | Depends on the final approach |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Look for an understanding of dynamic programming and state transitions.
- question_mark
Evaluate the ability to optimize a solution based on greedy subarray splits.
- question_mark
Test the candidate's ability to calculate and maximize subarray costs effectively.
常见陷阱
外企场景- error
Not properly identifying valid alternating subarrays.
- error
Using a brute force method that doesn't take advantage of dynamic programming.
- error
Failing to consider all possible valid splits of the array.
进阶变体
外企场景- arrow_right_alt
Adjust the problem to handle larger arrays efficiently.
- arrow_right_alt
Implement a solution that handles various edge cases like single-element arrays.
- arrow_right_alt
Test with arrays containing both positive and negative values to explore different split patterns.