comments | difficulty | edit_url | rating | source | tags | ||||
---|---|---|---|---|---|---|---|---|---|
true |
困难 |
2050 |
第 134 场双周赛 Q4 |
|
给你一个整数数组 nums
和一个整数 k
,请你返回 nums
中有多少个子数组满足:子数组中所有元素按位 AND
的结果为 k
。
示例 1:
输入:nums = [1,1,1], k = 1
输出:6
解释:
所有子数组都只含有元素 1 。
示例 2:
输入:nums = [1,1,2], k = 1
输出:3
解释:
按位 AND
值为 1 的子数组包括:[1,1,2]
, [1,1,2]
, [1,1,2]
。
示例 3:
输入:nums = [1,2,3], k = 2
输出:2
解释:
按位 AND
值为 2 的子数组包括:[1,2,3]
, [1,2,3]
。
提示:
1 <= nums.length <= 105
0 <= nums[i], k <= 109
根据题目描述,我们需要求出数组
如果我们每次固定右端点
当我们从
因此,我们只需要枚举集合中的每个值,与
时间复杂度
class Solution:
def countSubarrays(self, nums: List[int], k: int) -> int:
ans = 0
pre = Counter()
for x in nums:
cur = Counter()
for y, v in pre.items():
cur[x & y] += v
cur[x] += 1
ans += cur[k]
pre = cur
return ans
class Solution {
public long countSubarrays(int[] nums, int k) {
long ans = 0;
Map<Integer, Integer> pre = new HashMap<>();
for (int x : nums) {
Map<Integer, Integer> cur = new HashMap<>();
for (var e : pre.entrySet()) {
int y = e.getKey(), v = e.getValue();
cur.merge(x & y, v, Integer::sum);
}
cur.merge(x, 1, Integer::sum);
ans += cur.getOrDefault(k, 0);
pre = cur;
}
return ans;
}
}
class Solution {
public:
long long countSubarrays(vector<int>& nums, int k) {
long long ans = 0;
unordered_map<int, int> pre;
for (int x : nums) {
unordered_map<int, int> cur;
for (auto& [y, v] : pre) {
cur[x & y] += v;
}
cur[x]++;
ans += cur[k];
pre = cur;
}
return ans;
}
};
func countSubarrays(nums []int, k int) (ans int64) {
pre := map[int]int{}
for _, x := range nums {
cur := map[int]int{}
for y, v := range pre {
cur[x&y] += v
}
cur[x]++
ans += int64(cur[k])
pre = cur
}
return
}
function countSubarrays(nums: number[], k: number): number {
let ans = 0;
let pre = new Map<number, number>();
for (const x of nums) {
const cur = new Map<number, number>();
for (const [y, v] of pre) {
const z = x & y;
cur.set(z, (cur.get(z) || 0) + v);
}
cur.set(x, (cur.get(x) || 0) + 1);
ans += cur.get(k) || 0;
pre = cur;
}
return ans;
}