
LeetCode78/90 子集
利用 dfs(深度优先搜索)函数遍历数组。 在每一次递归中,决定当前元素是否加入子集。 每次递归调用前,记录当前选择的元素数量。 每次递归返回时,将当前子集添加到结果中。 使用递归的方法,但在递归过程中记录已经选择过的元素,避免重复选择。 在递归过程中检查是否已经选择了当前元素,若已选择则不再选择。 输入数组可以包含重复元素。 在递归时,检查当前元素是否已经被选择过。 如果是,则进行下一个递归。 如果不是,则将当前元素加入子集并继续递归。
发布日期:2021-05-14 23:49:53
浏览次数:19
分类:精选文章
本文共 2487 字,大约阅读时间需要 8 分钟。
题目分析
第一个问题:得到所有可能的子集(幂集)
给定一个不含重复元素的整数数组 nums,返回该数组所有可能的子集。每个子集都不能包含重复元素。例如,输入 nums = [1, 2, 3],输出是所有 2^3=8 个子集。
为了实现这一点,可以使用递归的方法。每次递归选择当前元素是否加入子集,然后递归处理剩下的元素。这种方法的时间复杂度是 O(2^n),其中 n 是数组的长度。
代码实现思路:
这样的方法简单且有效,但不适合处理大量元素的情况,因为计算量会非常大。
第二个问题:得到所有可能的子集(幂集)
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集。子集仍然不能包含重复元素。例如,输入 nums = [1, 2, 2],输出是所有可能的不含重复子集。
这个问题比第一个问题复杂,因为必须排除重复子集。为了解决这个问题,可以采取以下方法:
在代码实现中:
需要注意的是,这种方法虽然能解决重复元素的问题,但对于包含大量重复元素的数组,递归深度和层数会增加,导致性能问题。
完整代码
第一个问题:得到所有可能的子集
功能说明代码
int resSize;int[] res;void dfs(int[] nums, int numsSize, int[][] returnColumnSizes, int[] s, int s_index, int[][] res, int temp) { res[resSize] = new int[s_index]; returnColumnSizes[resSize] = s_index; for (int i = 0; i < numsSize; i++) { // 生成所有可能的子集 // 复制当前状态到父节点 int[] newS = Arrays.copyOf(s, s_index + 1); newS[s_index] = nums[i]; dfs(nums, numsSize, returnColumnSizes, newS, s_index + 1, res, temp); } // Base case: 空集 if (s_index == 0) { return; }}
初始化调用
int main() { int numsSize = nums.length; int[][] returnColumnSizes = new int[n]; Arrays.fill(returnColumnSizes, 0); resSize = 0; dfs(nums, numsSize, returnColumnSizes, s, 0, res); return res;}
第二个问题:优化处理重复元素
功能说明代码
int resSize;int[][] res;int last搬家;void dfs(int[] nums, int numsSize, int[][] returnColumnSizes, int[] s, int s_index, int[][] res, int temp, int last) { // 这里检查当前元素是否是重复的元素 boolean isPreviouslySelected = false; // 为了防止重复选择,检查是否已经选了相同的元素 for (int j = 0; j < last; j++) { if (nums[j] == nums[last]) { isPreviouslySelected = true; break; } } // 调用递归 if (isPreviouslySelected) { return; } int lastIndex = last; res[resSize] = new int[s_index + 1]; returnColumnSizes[resSize] = s_index + 1; // 将当前元素加入s s[s_index] = nums[lastIndex]; // 递归调用 dfs(nums, numsSize, returnColumnSizes, s, s_index + 1, res, temp, lastIndex + 1); // 递归结束后,恢复状态 s = Arrays.copyOf(s, s_index);}int main() { int[] nums = numsArray; int[] s = new int[0]; int i; dfs(nums, nums.length, returnColumnSizes, s, 0, res, temp, 0); return res;}
需要注意的是,在代码中我们通过记录上次选择的位置 last 来判断是否已经选中相同的元素。如果已经选中,则跳过,避免重复选择同一个元素。这样可以确保每个子集中的元素都是唯一的。
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年04月25日 05时14分05秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
onFailure unexpected end of stream
2019-03-09
Flex 布局的自适应子项内容过长导致其被撑大问题
2019-03-09
PL/SQL 动态Sql拼接where条件
2019-03-09
Lua-table 一种更少访问的安全取值方式
2019-03-09
虚函数
2019-03-09
斐波那契数列两种算法的时间复杂度
2019-03-09
【自学Flutter】4.1 Material Design字体图标的使用(icon)
2019-03-09
C++清空队列(queue)方法
2019-03-09
【换行符】什么时候用cin.get()吃掉输入流中的换行符
2019-03-09
【二叉树】已知后序与中序求先序
2019-03-09
解决Nginx 404 not found问题
2019-03-09
广东外语外贸大学第三届网络安全大赛Writeup
2019-03-09
VS中 fatal error LNK1123: 转换到 COFF 期间失败 的解决方法
2019-03-09
ant design pro v5去掉右边content区域的水印
2019-03-09
JavaScript——使用iterator遍历迭代map,set集合元素
2019-03-09
Course Schedule II
2019-03-10
C#中文转换成拼音
2019-03-10
C++错误笔记
2019-03-10
SpringBoot使用RedisTemplate简单操作Redis的五种数据类型
2019-03-10