排列-组合-子集
1、不同数字全排列
[1,2,3] have the following permutations: [ [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>> permutes = new ArrayList<>(); List<Integer> permute = new ArrayList<>(); boolean[] hasVisited = new boolean[nums.length]; backtracking(permute, permutes, hasVisited, nums); return permutes; } private void backtracking(List<Integer> permute,List<List<Integer>> permutes,boolean[] visited,int[] nums){ if(permute.size() == nums.length){ permutes.add(new ArrayList<>(permute)); return; } for(int i=0;i<visited.length;i++){ if(visited[i]){ continue; } visited[i] = true; permute.add(nums[i]); backtracking(permute, permutes, visited, nums); permute.remove(permute.size()-1); visited[i] = false; } }
2、相同数字全排列
[1,1,2] have the following unique permutations: [[1,1,2], [1,2,1], [2,1,1]]
public List<List<Integer>> permuteUnique(int[] nums){ List<List<Integer>> permutes = new ArrayList<>(); List<Integer> permute = new ArrayList<Integer>(); boolean[] hasVisited = new boolean[nums.length]; Arrays.sort(nums); backtrackingUnique(permute, permutes, hasVisited,nums); return permutes; } private void backtrackingUnique(List<Integer> permute,List<List<Integer>> permutes,boolean[] visited, int[] nums){ if(permute.size()==nums.length){ permutes.add(new ArrayList<Integer>(permute)); } for(int i=0;i<visited.length;i++){ if(i!=0 && nums[i]==nums[i-1] && !visited[i-1]){ continue; } if(visited[i]){ continue; } visited[i] = true; permute.add(nums[i]); backtrackingUnique(permute, permutes, visited, nums); permute.remove(permute.size()-1); visited[i] = false; } }
3、组合一
If n = 4 and k = 2, a solution is: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
public List<List<Integer>> combine(int n,int k){ List<List<Integer>> combinations = new ArrayList<>(); List<Integer> combination = new ArrayList<Integer>(); backtracking(combination, combinations, 1,k,n); return combinations; } private void backtracking(List<Integer> combination,List<List<Integer>> combinations,int start,int k,int n){ if(k==0){ combinations.add(new ArrayList<Integer>(combination)); return; } for(int i=start;i<=n-k+1;i++){ combination.add(i); backtracking(combination, combinations, i+1, k-1, n); combination.remove(combinations.size()-1); } }
4、组合二
given candidate set [2, 3, 6, 7] and target 7, A solution set is: [[7],[2, 2, 3]]
public List<List<Integer>> combinationSum(int[] candidates,int target){ List<List<Integer>> combinations = new ArrayList<>(); List<Integer> combination = new ArrayList<>(); backtracking(combination, combinations, 0,target,candidates); return combinations; } private void backtracking(List<Integer> combination,List<List<Integer>> combinations,int start,int target,int[] candidates){ if(target == 0){ combinations.add(new ArrayList<Integer>(combination)); return; } for(int i=start;i<candidates.length;i++){ if(candidates[i]<=target){ combination.add(candidates[i]); backtracking(combination, combinations, i,target-candidates[i],candidates); combination.remove(combination.size()-1); } } }
5、相同元素组合
For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
public List<List<Integer>> combinationSum2(int[] candidates,int target){ List<List<Integer>> combinations = new ArrayList<List<Integer>>(); List<Integer> combination = new ArrayList<>(); Arrays.sort(candidates); backtracking(combination, combinations, new boolean[candidates.length],0,target,candidates); return combinations; } private void backtracking(List<Integer> combination,List<List<Integer>> combinations,boolean[] hasVisited,int start,int target, int[] candidates){ if(target==0){ combinations.add(new ArrayList<>(combination)); return; } for(int i=start;i<candidates.length;i++){ if(i!=0 && candidates[i] == candidates[i-1] && !hasVisited[i-1]){ continue; } if(candidates[i]<=target){ combination.add(candidates[i]); hasVisited[i] = true; backtracking(combination, combinations, hasVisited,i+1,target-candidates[i],candidates); hasVisited[i] = false; combination.remove(combination.size()-1); } } }
6、子集
public List<List<Integer>> subsets(int[] nums){ List<List<Integer>> subsets = new ArrayList<>(); List<Integer> subset = new ArrayList<Integer>(); backtracking(0, subset, subsets,nums); return subsets; } private void backtracking(int start,List<Integer> subset,List<List<Integer>> subsets,int[] nums){ subsets.add(new ArrayList<>(subset)); for(int i = start;i<nums.length;i++){ subset.add(nums[i]); backtracking(i+1, subset, subsets,nums); subset.remove(subset.size()-1); } }
7、相同元素求子集
For example, If nums = [1,2,2], a solution is: [ [2], [1], [1,2,2], [2,2], [1,2], [] ]
public List<List<Integer>> subsetsWithDup(int[] nums){ List<List<Integer>> list = new ArrayList<>(); List<Integer> temp = new ArrayList<Integer>(); boolean[] hasVisited = new boolean[nums.length]; Arrays.sort(nums); backtracking(0, temp, list,hasVisited,nums); return list; } private void backtracking(int start,List<Integer> subset,List<List<Integer>> subsets,boolean[] hasVisited,int[] nums){ subsets.add(new ArrayList<>(subset)); for(int i=start;i<nums.length;i++){ if(i!=0 && nums[i]==nums[i-1] && !hasVisited[i-1]){ continue; } subset.add(nums[i]); hasVisited[i] = true; backtracking(i+1, subset, subsets,hasVisited,nums); hasVisited[i] = false; subset.remove(subset.size()-1); } }