题目链接:78. 子集
题解:
与之前的题几乎一致:AcWing-92.递归实现指数型枚举
题目简述:
给定一个集合,枚举所有子集,包括空集!
题解一:使用二进制
和之前题一样,做法一模一样:
每个数选与不选两种情况,一共有0 ~ 1 << nums.size() - 1
种情况,枚举每个二进制位是否为1即可!
时间复杂度: 一共枚举2n 个数,每个数枚举n位,总时间复杂度为 O(2n * n)
注意: 当 n >= 30时,2n > 109 会超时
AC代码一:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Solution { public: vector<vector<int>> subsets(vector<int>& nums) { vector<vector<int>> res; for(int state = 0; state < 1 << nums.size(); state ++){ vector<int> path; for(int k = 0; k < nums.size(); k++) if(state >> k & 1) path.push_back(nums[k]); res.push_back(path); } return res; } };
|
题解二:使用DFS
思路:
- 使用
for
循环分别去搜索位数为0 ~ nums.size()
的序列
dfs(int u, int cnt, int start)
:参数分别为 目标位数,当前第几位,下一次的起始位置(防止重复)
AC代码二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: vector<vector<int>> res; vector<int> path; vector<int> nums; vector<vector<int>> subsets(vector<int>& _nums) { nums = _nums; sort(nums.begin(), nums.end()); for(int i = 0; i <= nums.size(); i++) dfs(i, 0, 0); return res; } void dfs(int u, int cnt, int start){ if(cnt == u){ res.push_back(path); return; } for(int i = start; i < nums.size(); i++){ path.push_back(nums[i]); dfs(u, cnt + 1, i + 1); path.pop_back(); } } };
|