题目描述
给你一个整数数组 nums
和一个整数 k
,请你返回 nums
中有多少个子数组满足:子数组中所有元素按位 AND
的结果为 k
。
子数组是数组中连续的非空元素序列。
数据范围
1 ≤ nums.length ≤ 10^5
0 ≤ nums[i], k ≤ 10^9
解题思路
定义如下数组
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[i-1] & nums[i]
x =num[i-2] & num[i-1] & 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)
,其中,n
为 nums
的长度,m
为解题思路中 j
的种类。
空间复杂度:O(m)
。
END
文章文档:公众号 字节幺零二四
回复关键字可获取本文文档。
题目来源:力扣第134场双周赛T4:子数组按位与值为K的数目
文章声明:题目来源 力扣 平台,如有侵权,请联系删除!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。