525. Contiguous Array & 325. Maximum Size Subarray Sum Equals k

一道之前知道思路的题目,差点翻车没有做出来。
自己没想起来之前想到的方法有:dp,滑动窗口,前缀和。这次能够都想到滑动窗口和前缀和是不错的,因为这种区间的题目就应该这样。只不过没有下面这个特殊的思路确实不太好思考。
把所有的0当成-1,计算前缀和。一段区间中它的和为0,表示其中0和1个数相等。不需要真的计算每段区间,因为只要最长区间,保持每个前缀和出现的最小位置。
class Solution {
public:
int findMaxLength(vector<int>& nums) {
unordered_map<int, int> minIdx;//记录每个前缀和出现的最小index
minIdx[0] = -1;
int maxLen = 0;
int sum = 0;
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i] == 0 ? -1 : 1;
if (minIdx.find(sum) == minIdx.end())
minIdx[sum] = i;
else
maxLen = max(maxLen, i - minIdx[sum]);
}
return maxLen;
}
};
如果没有想出来把0变为-1,那么应该还是用前缀和,但是记录的是0的个数和1的个数的差别。其实道理是一样的。
类似的一题:

class Solution {
public:
int maxSubArrayLen(vector<int>& nums, int k) {
unordered_map<int, int> minIdx;//前缀和出现的最小位置
minIdx[0] = -1;
int sum = 0;
int maxLen = 0;
for (int i = 0; i < nums.size(); ++i) {
sum += nums[i];
if (minIdx.find(sum - k) != minIdx.end())
maxLen = max(maxLen, i - minIdx[sum - k]);
if (minIdx.find(sum) == minIdx.end())
minIdx[sum] = i;
}
return maxLen;
}
};
浙公网安备 33010602011771号