Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
一、题目:
leetcode 子集
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
提示:
1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同
二、题解:
1.解读 也就是需要返回nums所有的可能子集,因为元素都没有相同的,所以不用考虑重复元素了。
方法一 逐个枚举,先加入空的子集,然后遍历nums数组,每获取一个元素,就往之前的集合中追加上这个元素。
方法二
还有一种就是先取出nums数组的每个元素,然后把这个元素当做子集的第一个元素,再枚举剩余的可能。例如[1, 2, 3]数组,首先加入空集,然后循环获取数组元素,第一个元素为1,那就考虑子集为1开始的集合,除了1本身还可以组成[1, 2]或者[1, 2, 3]的子集;然后再以2开始,那这时之后获取的元素不能从下标1开始了,而是要从当前元素的下一个元素开始,不然的话会重复获取[2, 1]这种,所以又有子集[2, 3],最后后面就只有[3]了,循环结束之后就可以返回最终的所有子集了。
三、代码:
方法一
class Solution {
public static List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
res.add(new ArrayList<Integer>());
for (Integer num : nums) {
int size = res.size();
for (int i = 0; i < size; i++) {
List<Integer> temp = new ArrayList<Integer>(res.get(i));
temp.add(num);
res.add(temp);
}
}
return res;
}
}
时间复杂度:O(2^^n),双重循环添加子元素。 空间复杂度:O(2^n)。
方法二
class Solution {
List<Integer> temp = new ArrayList<Integer>();
List<List<Integer>> res = new ArrayList<List<Integer>>();
public List<List<Integer>> subsets(int[] nums) {
dfs(0, nums);
return res;
}
public void dfs(int cur, int[] nums) {
if (cur == nums.length) {
res.add(new ArrayList<Integer>(temp));
return;
}
temp.add(nums[cur]);
dfs(cur + 1, nums);
temp.remove(temp.size() - 1);
dfs(cur + 1, nums);
}
}
时间复杂度:O(2^n)。 空间复杂度:O(n)。