方法1: dp。就是找规律,具体思路解释可以看lc官方解释1,说得还是挺明白的。这个方法需要注意的是deep copy这个问题,我自己的代码是用loop来copy list的,但是lc官方答案里面没用这个方法,我不知道为什么,复盘的时候要去看一下lc方法1的代码和我自己的区别在哪里。时间复杂n*2的n次方,空间复杂same。
// 我的代码
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if(nums.length == 1) {
res.add(new ArrayList<>());
res.add(new ArrayList<>());
res.get(1).add(nums[0]);
return res;
}
List<List<Integer>> list1 = subsets(Arrays.copyOfRange(nums, 0, nums.length - 1));
List<List<Integer>> list2 = new ArrayList<>();
int curr = nums[nums.length-1];
for(List<Integer> l : list1){
res.add(l);
List<Integer> temp = new ArrayList<>();
for(Integer i : l) temp.add(i);
list2.add(temp);
}
for(List<Integer> l : list2){
l.add(curr);
res.add(l);
}
return res;
}
}
// lc方法1代码:
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> output = new ArrayList();
output.add(new ArrayList<Integer>());
for (int num : nums) {
List<List<Integer>> newSubsets = new ArrayList();
for (List<Integer> curr : output) {
newSubsets.add(new ArrayList<Integer>(curr){{add(num);}});
}
for (List<Integer> curr : newSubsets) {
output.add(curr);
}
}
return output;
}
}
方法2: backtracking,不是很好理解。我暂时不要求自己掌握。时间复杂空间复杂同方法1.
class Solution {
List<List<Integer>> output = new ArrayList();
int n, k;
public void backtrack(int first, ArrayList<Integer> curr, int[] nums) {
// if the combination is done
if (curr.size() == k)
output.add(new ArrayList(curr));
for (int i = first; i < n; ++i) {
// add i into the current combination
curr.add(nums[i]);
// use next integers to complete the combination
backtrack(i + 1, curr, nums);
// backtrack
curr.remove(curr.size() - 1);
}
}
public List<List<Integer>> subsets(int[] nums) {
n = nums.length;
for (k = 0; k < n + 1; ++k) {
backtrack(0, new ArrayList<Integer>(), nums);
}
return output;
}
}
方法3: bit manipulation。这是一个非常巧妙的方法,详细解释见lc官方解答3,说得很清楚。这个方法一定要掌握,我现在没有自己实现,复盘记得要自己实现一下。时间复杂空间复杂同上两个方法。
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> output = new ArrayList();
int n = nums.length;
for (int i = (int)Math.pow(2, n); i < (int)Math.pow(2, n + 1); ++i) {
// generate bitmask, from 0..00 to 1..11
String bitmask = Integer.toBinaryString(i).substring(1);
// append subset corresponding to that bitmask
List<Integer> curr = new ArrayList();
for (int j = 0; j < n; ++j) {
if (bitmask.charAt(j) == '1') curr.add(nums[j]);
}
output.add(curr);
}
return output;
}
}
总结:
- 无