题目
题目来源:力扣(LeetCode)
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
思路分析
回溯
/*** @param {number[]} nums* @return {number[][]}*/var subsets = function (nums) {const t = []; // 子集const ans = [];const dfs = (cur) => {if (cur === nums.length) { // 指针越界ans.push(t.slice()); // 将当前子集加入解集return; // 结束当前递归}t.push(nums[cur]); // 选择当前数dfs(cur + 1, nums); // 基于选择的这个数,继续往下递归,考察下一个数t.pop(t.length - 1); // 撤销选择当前数dfs(cur + 1, nums); // 不选择这个数后,继续往下递归,考察下一个数}dfs(0, nums);return ans;};
二进制 + 位运算
数组的子集个数为 1 << n ,即 2^n,其中n为数组的元素总数
/*** @param {number[]} nums* @return {number[][]}*/var subsets = function (nums) {const ans = [];const n = nums.length;// 数组的子集个数为 1 << n ,即 2^n// 遍历所有子集for (let mask = 0; mask < (1 << n); ++mask) {const t = []; // 存放元素的子集,子集个数总共为 1 << n ,即 2^nfor (let i = 0; i < n; ++i) {// 构造数字代表的集合,各元素存储至 t 子集中// 1 << i 即为构造nums数组的第 i 个元素// 若 mask & (1 << i) 为真,表示当前的 nums[i]不在当前的子集中,则nums[i]放入 t 子集中if (mask & (1 << i)) {t.push(nums[i]);}}ans.push(t);}return ans;};
