问题描述
Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,2], a solution is:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
算法分析
将所有重复的子序列给去除。在78Subsets的基础上添加了新的功能,如果想去重一定需要对nums数组进行排序。这个题目做的并不好,后期会重新做这题。对递归的理解还差点意思。
解法1
/**
* 如果当前的数和上一个数不同,冲0开始将所有的数都进行加一遍。
* 如果相同,这会将上一轮中的数进行计算一遍
* 一个
*
* @param nums
* @return
*/
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
Arrays.sort(nums);
result.add(new ArrayList<Integer>());
int count = 1;
for (int i = 0; i < nums.length; i++) {
int length = result.size();
int start = 0;
if (i != 0 && nums[i] == nums[i - 1]) {
start = length - count;
}
count = 0;
for (int j = start; j < length; j++) {
List<Integer> temp = new ArrayList<Integer>(result.get(j));
temp.add(nums[i]);
result.add(temp);
count++;
}
}
return result;
}
这题使用了组合的方式。如果是一个新的元素,为result中所有的元素都append上nums[i].如果nums[i]== nums[i-1],那么只对nums[i-1]append过的元素进行append上nums[i].
代码实现二
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
Arrays.sort(nums);
result.add(new ArrayList<Integer>());
for (int i = 0; i < nums.length; ) {//nums中所有的元素
int count = 1;
while (count + i < nums.length && nums[i] == nums[i + count]) count++;
int size = result.size();
for (int j = 0; j < size; j++) {
List<Integer> temp = new ArrayList<Integer>(result.get(j));
for (int k = 0; k < count; k++) {
temp.add(nums[i + k]);
result.add(new ArrayList<Integer>(temp));
}
}
i = i + count;
}
return result;
}
把连续的元素当成一个特殊的元素,但是会append多个元素。
举例 [2,2,2]被当成一个元素,但是这个元素会被append3次。[2],[2,2]和[2,2,2].
代码三
/**
* 使用回溯法解决这个问题
*
* @param nums
* @return
*/
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
List<Integer> temp = new ArrayList<Integer>();
Arrays.sort(nums);
subS(result, temp, nums, 0);
return result;
}
/**
* 将之前就的数结束
* 使用回溯法将其中重复的值给过滤掉
*
* @param result
* @param temp
* @param nums
* @param index
*/
private void subS(List<List<Integer>> result, List<Integer> temp, int[] nums, int index) {
result.add(new ArrayList<Integer>(temp));
for (int i = index; i < nums.length; i++) {
if (i > index && nums[i] == nums[i - 1]) continue;
temp.add(nums[i]);
subS(result, temp, nums, i + 1);
temp.remove(temp.size() - 1);
}
}