力扣第134场双周赛压轴题:子数组按位与值为K的数目

题目描述

给你一个整数数组 nums 和一个整数 k ,请你返回 nums 中有多少个子数组满足:子数组中所有元素按位 AND 的结果为 k

子数组是数组中连续的非空元素序列。

数据范围

  • 1nums.length105
  • 0nums[i],k109

解题思路

定义如下数组

map<int,int> dp[]

dp[i][j] 为以 nums[i] 结尾的子数组中,按位与的结果为 j 的子数组的数量,由 dp[i] 可计算得到 dp[i+1]

考虑 j 的种类,以下列出了每个以 nums[i] 结尾的子数组按位与的结果,j 种类最多的情况是,每个 x 的值可由上一个 x 将某一位 1 置为 0(与操作不能将某位 0 置为 1)得到。

  • x=nums[i]
  • x=num[i1] & nums[i]
  • x=num[i2] & num[i1] & nums[i]
  • ...

由于 nums[i] 最多有 32 位为 1,所以,j 的种类不超过 32,时间和空间复杂度满足要求。

代码实现

long long countSubarrays(vector<int> &nums, int k) {
    long long res = 0;
    unordered_map<int, int> pre;
    for (auto &num: nums) {
        unordered_map<int, int> cur = {{num, 1}};
        // num[i]本身值为k
        if (num == k)res++;
        // 由pre得到cur
        for (auto &[r, m]: pre) {
            int t = r & num;
            cur[t] += m;
            if (t == k)res += m;
        }
        pre = cur;
    }
    return res;
}

时间复杂度:O(nm),其中,nnums 的长度,m 为解题思路中 j 的种类。

空间复杂度:O(m)

END

文章文档:公众号 字节幺零二四 回复关键字可获取本文文档。

题目来源:力扣第134场双周赛T4:子数组按位与值为K的数目

文章声明:题目来源 力扣 平台,如有侵权,请联系删除!

posted @ 2024-07-07 01:19  字节幺零二四  阅读(5)  评论(0)    收藏  举报
编辑推荐:
· 如何正确实现一个 BackgroundService
· 抽象与性能:从 LINQ 看现代 .NET 的优化之道
· AI 时代,为什么我们还有必要写博客?
· 行业思考:不是前端不行,是只会前端不行
· C#高级GDI+实战:从零开发一个流程图
阅读排行:
· 记一次酣畅淋漓的js逆向
· 一个被BCL遗忘的高性能集合:C# CircularBuffer<T>深度解析
· 上周热点回顾(7.28-8.3)
· Trae Plus 让没有编程基础的女朋友也用上了 AI Coding
· 架构师必备:实时对账与离线对账
点击右上角即可分享
微信分享提示