排列-组合-子集

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);
        }
    }

 

posted @ 2020-08-06 14:11  helloworldmybokeyuan  阅读(130)  评论(0编辑  收藏  举报