【LetMeFly】2597.美丽子集的数目:二进制枚举-一个实现起来容易但非最优的方法
力扣题目链接:https://leetcode.cn/problems/the-number-of-beautiful-subsets/
给你一个由正整数组成的数组 nums
和一个 正 整数 k
。
如果 nums
的子集中,任意两个整数的绝对差均不等于 k
,则认为该子数组是一个 美丽 子集。
返回数组 nums
中 非空 且 美丽 的子集数目。
nums
的子集定义为:可以经由 nums
删除某些元素(也可能不删除)得到的一个数组。只有在删除元素时选择的索引不同的情况下,两个子集才会被视作是不同的子集。
示例 1:
输入:nums = [2,4,6], k = 2 输出:4 解释:数组 nums 中的美丽子集有:[2], [4], [6], [2, 6] 。 可以证明数组 [2,4,6] 中只存在 4 个美丽子集。
示例 2:
输入:nums = [1], k = 1 输出:1 解释:数组 nums 中的美丽数组有:[1] 。 可以证明数组 [1] 中只存在 1 个美丽子集。
提示:
1 <= nums.length <= 20
1 <= nums[i], k <= 1000
解题方法:二进制枚举
使用二进制下长度为 l e n ( n u m s ) len(nums) len(nums)的一个数,第 i i i位为 0 0 0代表选择 n u m s [ i ] nums[i] nums[i]否则代表不选 n u m s [ i ] nums[i] nums[i]。
从 1 1 1到 2 l e n ( n u m s ) 2^{len(nums)} 2len(nums)枚举这个数,就能得到所有的非空子集。
对于每个子集,暴力判断是否存在两个数只差为 k k k即可。
- 时间复杂度 O ( 2 n k 2 ) O(2^nk^2) O(2nk2),其中 n = l e n ( n u m s ) n=len(nums) n=len(nums)
- 空间复杂度 O ( n ) O(n) O(n)
AC代码
C++
/*
* @Author: LetMeFly
* @Date: 2025-03-07 23:32:24
* @LastEditors: LetMeFly.xyz
* @LastEditTime: 2025-03-07 23:49:07
* @Description: AC,6771ms击败5.56%,567.46MB击败5.56%
*/
class Solution {
private:
bool isok(vector<int>& v, int k) {
for (int i = 0; i < v.size(); i++) {
for (int j = i + 1; j < v.size(); j++) {
if (abs(v[i] - v[j]) == k) {
return false;
}
}
}
return true;
}
public:
int beautifulSubsets(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
int ans = 0;
int n = nums.size(), end = 1 << n;
for (int i = 1; i < end; i++) {
vector<int> v;
for (int j = 0; j < n; j++) {
if (i >> j & 1) {
v.push_back(nums[j]);
}
}
ans += isok(v, k);
}
return ans;
}
};
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源