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;
    }
};
posted @ 2019-10-04 19:54  于老师的父亲王老爷子  阅读(9)  评论(0)    收藏  举报