You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
首先看到k,可以想到利用%k进行分组,这样保证了每组相互间不会形成绝对值之差为k的subset,每组进行数量相乘就可以求出最终答案。接着,要计算组内能形成满足条件的subset,则利用了198. House Robber题型的思想,对组内数组排序后计算相邻差不为k的个数。
class Solution {
public int beautifulSubsets(int[] nums, int k) {
Map<Integer, TreeMap<Integer, Integer>> map = new HashMap<>();
for (int num : nums) {
int key = num % k;
map.putIfAbsent(key, new TreeMap<>());
map.get(key).put(num, map.get(key).getOrDefault(num, 0) + 1);
}
int res = 1;
for (int key : map.keySet()) {
int pre = -1, dp0 = 1, dp1 = 0;
for (int num : map.get(key).keySet()) {
int v = (int) (Math.pow(2, map.get(key).get(num)) - 1);
if (num - pre == k) {
int t = dp1;
dp1 = (dp0 * v);
dp0 += t;
} else {
int t = dp1;
dp1 = (dp0 + dp1) * v;
dp0 += t;
}
pre = num;
}
res *= (dp0 + dp1);
}
return res - 1;
}
}
原题地址:2597. The Number of Beautiful Subsets
参考资料:
这道题一开始没有什么特别思路,卡在不知道如何利用绝对值差为k这一条件。再观察数组长度和元素大小,就知道要用DFS递归,可能要用上记忆化搜索或者状态压缩。首先试着用暴力递归写了一版。
注意:
这是暴力递归的常规写法,没想到直接过了。赛后看其他人的留言,发现C++/python这样写会TLE,所以这是钻了编译器的空子,侥幸过了:)
那么尝试优化。那就要利用好绝对值之差为k这一条件了。
首先看下能不能用记忆化搜索,或者说缓存。换句话说,要看下有没有重复计算的部分,貌似没头绪。
接着看下能不能用状态压缩/DP,有人写了类似的做法但超时了,可以有空看看。
最后根据[Python] House Robber, O(n) By lee215的做法,利用不想交集合相乘和HashMap计算。
首先看到k,可以想到利用%k进行分组,这样保证了每组相互间不会形成绝对值之差为k的subset,每组进行数量相乘就可以求出最终答案。接着,要计算组内能形成满足条件的subset,则利用了198. House Robber题型的思想,对组内数组排序后计算相邻差不为k的个数。
这种求subset个数类型的题目,最终利用集合相乘和Hash的方法,最近还有一道类似的题目:2572. Count the Number of Square-Free Subsets
The text was updated successfully, but these errors were encountered: