子数组和问题

题记

穷则前缀哈希
达则滑动窗口
---鲁迅

前缀哈希

560. 和为K的子数组(统计子数组个数)

560. 和为K的子数组

因为没有正整数的约束,无法用滑窗

前缀和 + hash表

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        mp=collections.defaultdict(int)
        mp[0]=1
        pre=0
        count=0
        for num in nums:
            pre+=num
            if pre-k in mp:
                count+=mp[pre-k]
            mp[pre]+=1
        return count

325. 和等于 k 的最长子数组长度(统计子数组最大长度)

325. 和等于 k 的最长子数组长度

class Solution:
    def maxSubArrayLen(self, nums: List[int], k: int) -> int:
        n=len(nums)
        # 上题存个数,这题存下标
        pre_idx = defaultdict(int)
        res=0
        pre=0
        # 忘了写这个
        pre_idx[0] = -1
        for i in range(n):
            pre+=nums[i]
            if pre not in pre_idx:
                pre_idx[pre]=i
            if pre-k in pre_idx:
                res=max(res, i-pre_idx[pre-k])
        return res

523. 连续的子数组和

523. 连续的子数组和

有空看

滑动窗口

209. 长度最小的子数组

209. 长度最小的子数组
在这里插入图片描述

有正整数的约束,用滑窗 O ( n ) O(n) O(n)

但也可以用前缀和+二分, O ( n log ⁡ n ) O(n\log n) O(nlogn)

class Solution {
    
    
public:
    int minSubArrayLen(int target, vector<int> &nums) {
    
    
        int sum = 0, l = 0, sz = nums.size() + 1;
        for (int r = 0; r < nums.size(); ++r) {
    
    
            sum += nums[r];
            while (sum >= target) {
    
    
                int cur_sz = r - l + 1;
                if (cur_sz < sz) sz = cur_sz;
                sum -= nums[l++];
            }
        }
        return sz == nums.size() + 1 ? 0 : sz;
    }
};

猜你喜欢

转载自blog.csdn.net/TQCAI666/article/details/114987924
今日推荐