打算坚持一个星期的每日一题
标题:Maximum Abosolute Sum of Any Subarray
题目:You are given an integer array nums, the absolute sum of a subarray [nums_l, nums_l+1, ..., nums_r-1, nums_r] is abs(nums_l + nums_l+1 + ...+nums_r-1 + nums_r). Return the maximum absolute sum of any (possibly empty) subarray of nums.
Note that abs(x) is defined as follows:
- if x is a negative integer, then abs(x) = -x.
- if x is a non-negative integer, then abs(x) = x.
例子:
Example 1:
Input: nums = [1,-3,2,3,-4] Output: 5 Explanation: The subarray [2,3] has absolute sum = abs(2+3) = abs(5) = 5.
Example 2:
Input: nums = [2,-5,1,-4,3,-2] Output: 8 Explanation: The subarray [-5,1,-4] has absolute sum = abs(-5+1-4) = abs(-8) = 8.
Constrains:
- 1 <= nums.length <= 1e5
- -1e4 <= nums[i] <= 1e4
解题思路:与2025/4/25的每日一题类似。看到数据规模是1e5,就知道这道题不能用时间复杂度为O(n^2)的方法来做。看到结果是只返回一个sum数,就猜想肯定能用O(n)的方法来做了。因为是计算绝对值的最大值,所以原始值可能为正数,也可能为负数。因此维护两个整型变量:neg(记录到i位置的和的负数),pos(记录到i位置的和的正数)。表达的可能有点难理解,可以这样想象:在遍历数组时,维持两条路,一条记录所有负值和的情况,一条记录所有正值和的情况。如果负值和大于0,则斩断,因为即使再加负值不会比0加负值更小了(即斩断子序列)。同理,如果正值和小于0,也斩断。
例:
数组 | 2 | -5 | 1 | -4 | 3 | -2 |
---|---|---|---|---|---|---|
负数和 | 0 | -5 | -4 | -8 | -5 | -7 |
正数和 | 2 | 0 | 1 | 0 | 3 | 1 |
最大绝对值 | 2 | 5 | 5 | 8 | 8 | 8 |
代码:
class Solution {
public:
int maxAbsoluteSum(vector<int>& nums) {
int neg = 0, pos = 0, res = 0;
for (int i = 0; i < nums.size(); i++) {
neg += nums[i];
pos += nums[i];
if (neg > 0) neg = 0;
if (pos < 0) pos = 0;
res = max(max(res, -neg), pos);
}
return res;
}
};
时间复杂度:O(N)
空间复杂度:O(1)
结果:
不明白为啥O(1)的Memory才Beats 20.65%,都是神仙吗?