滑动窗口--3

2090. 半径为 k 的子数组平均值

题目来源:2090. 半径为 k 的子数组平均值 - 力扣(LeetCode)

题目:

分析:

  1. 由于半径为k,那么window就是 2 *k + 1,所以这是一个定长滑动窗口
  2. 那么定长滑动窗口端点指针的关系就是 :
    1. right - left +1 = 2*k +1
    2. left = right - 2*k
  3. 由于i索引前后半径不够k avg直接赋值为-1:
    1. 如果len(nums) < len(window) return [i for i in range(len(nums))]
    2. 如果条件一满足,那么left < 0 or right > len(nums) -1 时,avg = -1
  4. 因为right作为window右端点,那么如果加和随着索引i相加就会遗漏sum(nums[k:right + 1]),所以我首先想到了随right索引加和,将加和结果变量初始化为sum(nums[:k]),这样就可以实现滑动窗口的移动和移除

我的解:

class Solution:
    def getAverages(self, nums: List[int], k: int) -> List[int]:
        # 窗口长度为 2k + 1
        windows = 2*k + 1
        ans = list()
        length = len(nums)
        # 前或后不足 k 个元素 半径为 k 的子数组平均值 是 -1 
        if length < windows:
            return [-1 for i in range(length)]
        left = 0
        # 初始化 
        add = sum(nums[:k])
        for i in range(length):
            right = i + k
            left = right - 2*k
            if right >= length:
                ans.append(-1)
                continue
            else:
                add += nums[right]
            if left < 0 :
                ans.append(-1)
                continue
            # 更新 ans 数组
            ans.append(add//len(nums[left:right+1]))
            # 移除 windows末端数值
            add -= nums[left]
        return ans

题解:

class Solution:
    def getAverages(self, nums: List[int], k: int) -> List[int]:
        avgs = [-1] * len(nums)
        s = 0  # 维护窗口元素和
        for i, x in enumerate(nums):
            # 1. 进入窗口
            s += x
            if i < k * 2:  # 窗口大小不足 2k+1
                continue
            # 2. 记录答案
            avgs[i - k] = s // (k * 2 + 1)
            # 3. 离开窗口
            s -= nums[i - k * 2]
        return avgs

 结论:

  1. avgs = [-1] * len(nums) 初始化只需要O(1),后面遍历处理的数据量小于n
  2. 我的代码中初始化求sum以及根据窗口判断更新ans都会增加耗时

2379. 得到 K 个黑块的最少涂色次数

题目来源:2379. 得到 K 个黑块的最少涂色次数 - 力扣(LeetCode)

解答:

class Solution:
    def minimumRecolors(self, blocks: str, k: int) -> int:
        ans = inf
        left = 0 
        length = len(blocks)
        data = {'W':0,'B':0}
        for right in range(length):
            data[blocks[right]] += 1
            left = right + 1 - k
            if left < 0:
                continue
            ans = min(ans,data['W'])
            data[blocks[left]] -= 1
        return ans
            
        

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值