1994. 好子集的数目
给你一个整数数组 nums 。如果 nums 的一个子集中,所有元素的乘积可以表示为一个或多个 互不相同的质数 的乘积,那么我们称它为 好子集 。
比方说,如果 nums = [1, 2, 3, 4] :
[2, 3] ,[1, 2, 3] 和 [1, 3] 是 好 子集,乘积分别为 6 = 23 ,6 = 23 和 3 = 3 。
[1, 4] 和 [4] 不是 好 子集,因为乘积分别为 4 = 22 和 4 = 22 。
请你返回 nums 中不同的 好 子集的数目对 109 + 7 取余 的结果。
nums 中的 子集 是通过删除 nums 中一些(可能一个都不删除,也可能全部都删除)元素后剩余元素组成的数组。如果两个子集删除的下标不同,那么它们被视为不同的子集。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/the-number-of-good-subsets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
import java.util.*;
class Solution {
static final int[] PRIMES = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
static final Set<Integer> CANDIDATES = new HashSet<Integer>() {{
addAll(Arrays.asList(2, 3, 5, 6, 7, 10, 11, 13, 14, 15, 17, 19, 21, 22, 23, 26, 29, 30));
}};
static final Map<Integer, Integer> MASK = new HashMap<Integer, Integer>() {{
for (int x : CANDIDATES) {
int mask = 0;
for (int i = 0; i < PRIMES.length; ++i) {
if (x % PRIMES[i] == 0) {
mask |= (1 << i);
}
}
put(x, mask);
}
}};
static final int NUM_MAX = 30;
static final int MOD = 1000000007;
public int numberOfGoodSubsets(int[] nums) {
int[] freq = new int[NUM_MAX + 1];
for (int num : nums) {
++freq[num];
}
int[] f = new int[1 << PRIMES.length];
f[0] = 1;
for (int i = 0; i < freq[1]; ++i) {
f[0] = f[0] * 2 % MOD;
}
for (int i = 2; i <= NUM_MAX; ++i) {
if (freq[i] == 0 || !CANDIDATES.contains(i)) {
continue;
}
int subset = MASK.get(i);
for (int mask = (1 << PRIMES.length) - 1; mask > 0; --mask) {
if ((mask & subset) == subset) {
f[mask] = (int) ((f[mask] + ((long) f[mask ^ subset]) * freq[i]) % MOD);
}
}
}
int ans = 0;
for (int mask = 1, maskMax = (1 << PRIMES.length); mask < maskMax; ++mask) {
ans = (ans + f[mask]) % MOD;
}
return ans;
}
}
心之所向,素履以往 生如逆旅,一苇以航
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具