2597.美丽子集的数目:二进制枚举-一个实现起来容易但非最优的方法

【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

解题方法:二进制枚举

使用二进制下长度为$len(nums)$的一个数,第$i$位为$0$代表选择$nums[i]$否则代表不选$nums[i]$。

从$1$到$2^{len(nums)}$枚举这个数,就能得到所有的非空子集。

对于每个子集,暴力判断是否存在两个数只差为$k$即可。

  • 时间复杂度$O(2^nk^2)$,其中$n=len(nums)$
  • 空间复杂度$O(n)$

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
* @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和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源


2597.美丽子集的数目:二进制枚举-一个实现起来容易但非最优的方法
https://blog.letmefly.xyz/2025/03/08/LeetCode 2597.美丽子集的数目/
作者
Tisfy
发布于
2025年3月8日
许可协议