滑动窗口-4

 2841. 几乎唯一子数组的最大和

题目来源:2841. 几乎唯一子数组的最大和 - 力扣(LeetCode)

分析:

  1. 定长滑动窗口 right遍历元素,left = rigth + 1 - k(通过定长k推导,right - left + 1 = k)
  2. 除了窗口固定外,还需要保证窗口内的不同元素数 >= m,我选择使用字典来存储,当nums[left]在字典中value == 1的时候,需要将该元素移除,如果大于1,那么value减去1,不同元素数量不变

我的解:

class Solution:
    def maxSum(self, nums: List[int], m: int, k: int) -> int:
        ans = 0
        if len(nums) < k:
            return 0
        dic = dict()
        # m 必然小于 k
        ans_tmp = 0
        m_tmp = 0
        for right in range(len(nums)):
            ans_tmp += nums[right]
            if nums[right] not in dic:
                dic[nums[right]] = 0
                m_tmp += 1
            dic[nums[right]]  += 1
            left = right + 1 - k
            if left < 0:
                continue
            if m_tmp >= m:
                ans = max(ans,ans_tmp)
            ans_tmp -= nums[left]
            if dic[nums[left]] == 1:
                dic.pop(nums[left])
                m_tmp -= 1
            else:
                dic[nums[left]] -= 1
        return int(ans)

题解:

class Solution:
    def maxSum(self, nums: List[int], m: int, k: int) -> int:
        ans = s = 0
        cnt = defaultdict(int)
        for i, x in enumerate(nums):
            # 1. 进入窗口
            s += x
            cnt[x] += 1

            left = i - k + 1
            if left < 0:  # 窗口大小不足 k
                continue

            # 2. 更新答案
            if len(cnt) >= m:
                ans = max(ans, s)

            # 3. 离开窗口
            out = nums[left]
            s -= out
            cnt[out] -= 1
            if cnt[out] == 0:
                del cnt[out]

        return ans

作者:灵茶山艾府

2461. 长度为 K 子数组中的最大和

题目来源:2461. 长度为 K 子数组中的最大和 - 力扣(LeetCode)

我的解: 

class Solution:
    def maximumSubarraySum(self, nums: List[int], k: int) -> int:
        from math import inf
        dic = defaultdict(int)
        left = 0
        ans = -inf
        ans_tmp = 0
        # 存储不同元素数
        element = 0
        for right,num in enumerate(nums):
            if dic[num] == 0:
                element += 1
            ans_tmp += num
            dic[num] += 1
            left = right + 1 - k
            if left < 0:
                continue
            if element == k:
                ans = max(ans,ans_tmp)
            if dic[nums[left]] > 1:
                dic[nums[left]] -= 1
            elif dic[nums[left]] == 1:
                element -= 1
                dic[nums[left]] -= 1
            ans_tmp -= nums[left]
        if ans == -inf :
            return 0
        return ans 

题解:

class Solution:
    def maximumSubarraySum(self, nums: List[int], k: int) -> int:
        ans = s = 0
        cnt = defaultdict(int)
        for i, x in enumerate(nums):
            # 1. 进入窗口
            s += x
            cnt[x] += 1

            left = i - k + 1
            if left < 0:  # 窗口大小不足 k
                continue

            # 2. 更新答案
            if len(cnt) == k:
                ans = max(ans, s)

            # 3. 离开窗口
            out = nums[left]
            s -= out
            cnt[out] -= 1
            if cnt[out] == 0:
                del cnt[out]

        return ans

作者:灵茶山艾府

总结:
1. 不同元素的个数完全可以通过len(dic)来获取,没必要单独搞一个变量,同时不用担心时间开销,因为len操作时间复杂度为O(1)

2. 要常看题解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值