题目来源
题目描述
class Solution {
public:
int maxAbsoluteSum(vector<int>& nums) {
}
};
题目解析
前缀和
题目要求求一段连续的子数组和,所以可以用前缀和和。
先得到一个前缀和数组preSum,然后如果要求任意一段子数组[i,j]的和可以直接通过preSum[j] - preSum[i - 1]
得出。
要使得abs(preSum[j] - preSum[i - 1])
最大,有这么几种情况:
- 找到前缀和数组中的最大值减去最小值,得到一个最大正数(前提是最大值出现在最小值的后面,并且最小值是个负数,否则应该直接取最大值作为答案)
- 找到前缀和的最小值减去最大值,得到一个最小负数(前提是最小值出现在最大值的后面,而且最大值是一个正数,否则直接取最小值作为答案)。
也就是说最终答案只与前缀和数组中的最大值和最小值相关,而且最大值可能会出现在最小值前面或者后面。
因此我们可以边循环边做更新答案。
class Solution{
public:
int maxAbsoluteSum(vector<int>& nums) {
int n = nums.size();
std::vector<int> preSum(n + 1);
for (int i = 1; i <= n; ++i) {
preSum[i] = preSum[i - 1] + nums[i - 1];
}
int ans = 0, min = 0, max = 0;
for (int i = 0; i <= n; ++i) {
ans = std::max(ans, std::abs(preSum[i] - max));
ans = std::max(ans, std::abs(preSum[i] - min));
max = std::max(max, preSum[i]);
min = std::min(min, preSum[i]);
}
return ans;
}
};
动态规划
类似题目
题目 | 思路 |
---|---|
leetcode:53. 子数组最大累加和 maximum-subarray | |
leetcode:1749. 任意子数组和的绝对值的最大值maximum-absolute-sum-of-any-subarray |