leetcode 995 区间翻转问题,队列

思路一:滑动窗口
首先考虑第一个位置,只有一个窗口能翻转它。所以第一个窗口必须满足第一个位置。然后再看第二个元素,只有第一,第二个窗口能满足,第一个窗口是否翻转是固定的,所以第二个窗口是否翻转也固定,这样窗口一直滑动,咱们只需关心窗口的第一个元素就好。

class Solution:
    def minKBitFlips(self, A: List[int], K: int) -> int:
        ret = 0
        for i in range(len(A)-K+1):
            if A[i] == 0:
                ret += 1
                for j in range(i+1, i+K):
                    A[j] = 1 - A[j]

        for i in range(len(A)-K+1, len(A)):
            if A[i] == 0: return -1
        
        return ret

思路二:时间优化
提交后发现超时,说明需要O(N)的算法,即要用O(1)的时间复杂度记录每次翻转情况。关键在于,我们关心每个元素的前K个元素翻转了多少次。我们可以用一个队列把前K个元素翻转了的入队,然后用队列长度看这个元素是否需要翻转。

from heapq import *
class Solution:
    def minKBitFlips(self, A: List[int], K: int) -> int:
        ret = 0

        q = []
        heapify(q)
        
        for i in range(len(A)-K+1):
            if len(q) and i-q[0] >= K: heappop(q)
            if len(q)&1: A[i] = 1 - A[i]

            if A[i] == 0:
                ret += 1
                heappush(q, i)

        for i in range(len(A)-K+1, len(A)):
            if len(q) and i-q[0] >= K: heappop(q)
            if A[i] == len(q)&1: return -1
        
        return ret
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值