78. Subsets
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],
[]
]
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> alist = new ArrayList<>();
if(nums.length < 1)
return alist;
backTrack(alist,new ArrayList<>(), nums, 0);
return alist;
}
void backTrack(List<List<Integer>> alist, List<Integer> blist, int[] nums, int i){
if(i == nums.length){
alist.add(new ArrayList<>(blist));
return;
}
backTrack(alist,blist,nums,i + 1); //要这个值
blist.add(nums[i]);
backTrack(alist,blist,nums,i + 1); //不要最后一个
blist.remove(blist.size() - 1);
}
90. Subsets II
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
Input: [1,2,2]
Output:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<List<Integer>>();
backTracking2(nums, result, new ArrayList<>(), 0);
return result;
}
void backTracking(int[] nums, List<List<Integer>> alist, List<Integer> blist, int i) {
if(i == nums.length) {
if(!alist.contains(blist))
alist.add(new ArrayList<>(blist));
return;
}
backTracking(nums, alist, blist, i + 1); //要当前值
blist.add(nums[i]);
backTracking(nums, alist, blist, i + 1); //不要当前值
blist.remove(blist.size() - 1);
}
void backTracking2(int[] nums, List<List<Integer>> alist, List<Integer> blist, int i) {
if(blist.size() <= nums.length ) { //由于是子集,所以遇到的每一个值都有可能是答案
alist.add(new ArrayList<>(blist));
}
for (int j = i; j < nums.length; j++) {
if(j > i && nums[j] == nums[j - 1])
continue;
blist.add(nums[j]);
backTracking2(nums, alist, blist, j + 1);
blist.remove(blist.size() - 1);
}
}
46. Permutations
Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> alist = new ArrayList<List<Integer>>();
if(nums == null || nums.length < 1)
return alist;
Process(alist, new ArrayList<>(), nums);
return alist;
}
public void Process(List<List<Integer>> blist, List<Integer> clist, int[] nums){
if(clist.size() == nums.length){
blist.add(new ArrayList<>(clist));
return;
}
for (int j = 0; j < nums.length; j++) {
//swap(nums, i, j);
if(clist.contains(nums[j]))
continue;
clist.add(nums[j]);
Process(blist, clist, nums);
clist.remove(clist.size() - 1);
}
}
public void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
47. Permutations II
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
Example:
Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<List<Integer>>();
boolean[] u = new boolean[nums.length];
backTracking(result, new ArrayList<>(), nums, u);
return result;
}
public void backTracking(List<List<Integer>> alist, List<Integer> blist,
int[] nums, boolean[] used) {
if(blist.size() == nums.length) {
alist.add(new ArrayList<>(blist));
return;
}
for (int i = 0; i < nums.length; i++) {
if(used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]))
continue;
used[i] = true;
blist.add(nums[i]);
backTracking(alist, blist, nums, used);
used[i] = false;
blist.remove(blist.size() - 1);
}
}
39. Combination Sum
Given a set of candidate numbers (candidates
) (without duplicates) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
The same repeated number may be chosen from candidates
unlimited number of times.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[7],
[2,2,3]
]
Example 2:
Input: candidates = [2,3,5], target = 8,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List<List<Integer>> result = new ArrayList<List<Integer>>();
backTracking(candidates, target, 0, result, new ArrayList<>());
return result;
}
private void backTracking(int[] candidates, int target, int start,
List<List<Integer>> alist, List<Integer> blist) {
if(target == 0) {
alist.add(new ArrayList<>(blist));
return;
}
//导致出现重复是由于此处的i又从0开始计算的,
//因为i额数组已经排序好了,当走到数组中间的时候前面的已经走过了
for (int i = start; i < candidates.length; i++) {
if(candidates[i] <= target) {
blist.add(candidates[i]);
backTracking(candidates, target - candidates[i], i,alist, blist);
blist.remove(blist.size() - 1);
}
}
}
40. Combination Sum II
Given a collection of candidate numbers (candidates
) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
Each number in candidates
may only be used once in the combination.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
[1,2,2],
[5]
]
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
List<List<Integer>> result = new ArrayList<List<Integer>>();
backTracking(candidates, target, 0, result, new ArrayList<>());
return result;
}
void backTracking(int[] candidates, int target, int i,
List<List<Integer>> alist, List<Integer> blist) {
if(target == 0) {
alist.add(new ArrayList<>(blist));
return;
}//int i = start
for (; i < candidates.length; i++) {
if(target < candidates[i]) break;
blist.add(candidates[i]);
backTracking(candidates, target - candidates[i], i + 1, alist, blist);
blist.remove(blist.size() - 1);
//每次清除一个空位让后续元素加入。寻找成功,最后一个元素要退位,
//寻找不到,方法不可行,那么我们回退,也要移除最后一个元素。
while (i < candidates.length - 1 && candidates[i] == candidates[i + 1]) {
i++;
}
}
}