LeetCode 78. Subsets
Woodyiiiiiii opened this issue · comments
Given a set of distinct integers, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
Input: nums = [1,2,3]
Output:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
这道题显然不能纯粹使用暴力法,因为我们不知道到底有多少可能,只能观察数据找规律。
实际上每次存进线性表,可以看作在线性表的元素基础上加上新的nums数组中的元素,再存入线性表中。比如nums = {1, 2},一开始线性表初始化为[[]],元素只有一个,取出来加上元素1等于[1],再存入线性表中,线性表变为[[], [1]],同理,加入2后变为[[], [1], [2], [1, 2]]。
//C++ solution:
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int> > res(1);
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); ++i) {
int size = res.size();
for (int j = 0; j < size; ++j) {
res.push_back(res[j]);
res.back().push_back(nums[i]);
}
}
return res;
}
};
//Java solution:
class Solution {
public List<List<Integer>> subsets(int[] nums) {
int n = nums.length;
List<List<Integer>> res = new LinkedList();
if (n == 0) return res;
Arrays.sort(nums);
res.add(new LinkedList<Integer>());
for (int i = 0; i < n; ++i) {
int size = res.size();
for (int j = 0; j < size; ++j) {
res.add(new LinkedList<>(res.get(j)));
res.get(res.size() - 1).add(nums[i]);
}
}
return res;
}
}
注意Java跟C++的解法不同,因为Java容器类太不方便了。取出元素时使用get方法,然而实际上因为Java的值传递,我们并没有声明新的空间,存入线性表中的元素内存地址是一样的,所以如果按照C++的解法,在向某元素添加新的nums里的数值时,会对原本的线性表元素产生影响。比如,[[1]]中我想加入数值2,取出1加上2并存入线性表,然而线性表会变成[[1, 2], [1, 2]]而不是[[1], [1, 2]]。
当然实现了List接口的ArrayList和LinkedList类实现了clone函数,但是我们可以new一个list,初始化值是list类型:
res.add(new LinkedList<>(res.get(j)));
这道题我们也可用DFS+回溯法来做,原理同77. combinations:
class Solution {
public List<List<Integer>> subsets(int[] nums) {
int n = nums.length;
List<List<Integer>> res = new ArrayList<>();
if (n == 0) return res;
Arrays.sort(nums);
List<Integer> tmp = new ArrayList<>();
dfs(res, tmp, nums, 0);
return res;
}
public void dfs(List<List<Integer>> res, List<Integer> tmp, int[] nums, int start) {
res.add(new ArrayList<>(tmp));
if (tmp.size() == nums.length) return;
for (int i = start; i < nums.length; ++i) {
tmp.add(nums[i]);
dfs(res, tmp, nums, i + 1);
tmp.remove(tmp.size() - 1);
}
}
}
看大佬还有两种做法,分别是二叉树和列表,有兴趣可以点击参考资料去了解下。
参考资料: