The Number of Good Subsets
The Number of Good Subsets
You are given an integer array nums . We call a subset of nums good if its product can be represented as a product of one or more distinct prime numbers.
- For example, if nums = [1, 2, 3, 4] :
- [2,3] , [1, 2, 3] , and [1, 3] are good subsets with products 6 = 2*3 , 6 = 2*3 , and 3 = 3 respectively.
- [1, 4] and [4] are not good subsets with products 4 = 2*2 and 4 = 2*2 respectively.
Return the number of different good subsets in nums modulo .
A subset of nums is any array that can be obtained by deleting some (possibly none or all) elements from nums . Two subsets are different if and only if the chosen indices to delete are different.
Example 1:
Input: nums = [1,2,3,4] Output: 6 Explanation: The good subsets are: - [1,2]: product is 2, which is the product of distinct prime 2. - [1,2,3]: product is 6, which is the product of distinct primes 2 and 3. - [1,3]: product is 3, which is the product of distinct prime 3. - [2]: product is 2, which is the product of distinct prime 2. - [2,3]: product is 6, which is the product of distinct primes 2 and 3. - [3]: product is 3, which is the product of distinct prime 3.
Example 2:
Input: nums = [4,2,3,15] Output: 5 Explanation: The good subsets are: - [2]: product is 2, which is the product of distinct prime 2. - [2,3]: product is 6, which is the product of distinct primes 2 and 3. - [2,15]: product is 30, which is the product of distinct primes 2, 3, and 5. - [3]: product is 3, which is the product of distinct prime 3. - [15]: product is 15, which is the product of distinct primes 3 and 5.
Constraints:
解题思路
Count the Number of Square-Free Subsets的扩展版,扩大到了,当然题意也有些变化(港真lc直接把原题搬到周赛这样做真的好吗)。如果还是像这题一样的做法,由于时间复杂度为,那么一定会超时。
注意,由于每个数最大不超过,因此我们可以把值域定义为状态,而不是把下标定义为状态。
定义状态表示从数值中选择,乘积结果的状态为(即包含了哪些质数)的所有方案的个数。其中根据数值选或不选来划分状态。状态转移方程为
其中表示数值出现的次数(显然一个合法的结果的乘积只能乘一次,一次有多少个就有多少种方案)。如果本身就不合法(即某个质因子次数超过),那么很明显该数是不能选择的。为了方便这里把不合法的数的定义为,那么同样适用上面的状态转移方程。
为什么要从开始呢?的情况呢?该题的要求是“所有元素的乘积可以表示为一个或多个互不相同的质数的乘积”,而不是质数,因此乘积的结果不能是,但可以用去乘其他的数。我们把归为状态,显然,其他的可以从转移过来。
最后的答案就是,不从开始是为了不统计乘积结果为的情况。
AC代码如下,时间复杂度为:
1 class Solution { 2 public: 3 int mod = 1e9 + 7; 4 5 int numberOfGoodSubsets(vector<int>& nums) { 6 int primes[10] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29}; 7 vector<int> cnt(31), st(31); 8 for (auto &x : nums) { 9 bool flag = true; 10 int t = x; 11 for (int i = 0; i < 10; i++) { 12 int p = primes[i]; 13 if (t % p == 0) { 14 int s = 0; 15 st[x] |= 1 << i; 16 while (t % p == 0) { 17 s++; 18 t /= p; 19 } 20 if (s > 1) { 21 flag = false; 22 break; 23 } 24 } 25 } 26 if (flag) cnt[x]++; 27 } 28 vector<vector<int>> f(31, vector<int>(1 << 10)); 29 f[1][0] = 1; 30 while (cnt[1]--) { 31 f[1][0] = f[1][0] * 2 % mod; 32 } 33 for (int i = 2; i <= 30; i++) { 34 for (int j = 0; j < 1 << 10; j++) { 35 f[i][j] = f[i - 1][j]; 36 if ((j & st[i]) == st[i]) f[i][j] = (f[i][j] + 1ll* f[i - 1][j ^ st[i]] * cnt[i]) % mod; 37 } 38 } 39 int ret = 0; 40 for (int i = 1; i < 1 << 10; i++) { 41 ret = (ret + f[30][i]) % mod; 42 } 43 return ret; 44 } 45 };
参考资料
好子集的数目:https://leetcode.cn/problems/the-number-of-good-subsets/solution/hao-zi-ji-de-shu-mu-by-leetcode-solution-ky65/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17135416.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2022-02-19 波动数列