Leetcode 3209. Number of Subarrays With AND Value of K

1. 解题思路

这一题的话整体上是一个滑动窗口的思路,我们维护一个滑动窗口,确保其每一个窗口都是当右侧节点作为终点时,能够满足subarray的与操作结果刚好不为 k k k时的最长连续子串。

另一方面,我们另外维护一个forbidden point,其定义为某一个位置左侧第一个与 k k k的与操作不等于 k k k的值,那么,在这个范围区间内的所有subarray都必然满足其与操作的结果均为 k k k(显然,该范围内所有值与k的与操作都为k,即k不为0的位这些数也都不为0,另一方面,滑动窗口又保证这个区间内k为0的位上之上有一个数为0)。

2. 代码实现

给出python代码实现如下:

class Solution:
    def countSubarrays(self, nums: List[int], k: int) -> int:    
        kdigits = bin(k)[2:].rjust(32, "0")

        ans = 0
        
        pre_forbidden = -1
        lbound = 0
        num = 2**32-1
        cnt = defaultdict(int)
        for i, x in enumerate(nums):
            if x & k != k:
                pre_forbidden = i
                lbound = i+1
                num = 2**32-1
                cnt = defaultdict(int)
                continue
            digits = bin(x)[2:].rjust(32, "0")
            for j, d in enumerate(digits):
                if d == "0":
                    cnt[j] += 1
            num = num & x
            if num != k:
                continue
            while all(kdigits[j] == "1" or cnt[j] > 0 for j in range(32)):
                digits = bin(nums[lbound])[2:].rjust(32, "0")
                for j, d in enumerate(digits):
                    if d == "0":
                        cnt[j] -= 1
                lbound += 1
            ans += lbound-1-pre_forbidden
        return ans

提交代码评测得到:耗时5223ms,占用内存27.4MB。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值