利用回溯法解排列组合问题
程序员文章站
2022-03-03 11:27:48
...
回溯法简述
回溯法是一种优选的搜索法,又称试探法。按选优条件向前搜索,已达到目标。但当搜索到某一步时,发现原选择并不优或者达不到目标,就退一步重新选择。这种走不通就退回再走的技术称为回溯法。详见之前的文章 回溯法总结。
排列组合例题
以下三道为leetcode上有关排列组合的问题,分别是46、47和48题。
第一题: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] ]
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
backtrack(list, new ArrayList<>(), nums);
return list;
}
private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){
if(tempList.size() == nums.length){
list.add(new ArrayList<>(tempList));
} else{
for(int i = 0; i < nums.length; i++){
if(tempList.contains(nums[i])) continue; // element already exists, skip
tempList.add(nums[i]);
backtrack(list, tempList, nums);
tempList.remove(tempList.size() - 1);
}
}
}
}
第二题: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] ]
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
Set<List<Integer>> list = new HashSet<>();
boolean[] used = new boolean[nums.length];
backtrack(list, new ArrayList<>(), nums, used);
return new ArrayList<>(list);
}
private void backtrack(Set<List<Integer>> list, List<Integer> tempList, int[] nums, boolean[] used) {
if (tempList.size() == nums.length) {
list.add(new ArrayList<>(tempList));
} else {
for (int i = 0; i < nums.length; i++) {
if (used[i]) continue;
used[i] = true;
tempList.add(nums[i]);
backtrack(list, tempList, nums, used);
used[i] = false;
tempList.remove(tempList.size() - 1);
}
}
}
}
第三题: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], [] ]
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
backtrack(list, new ArrayList<>(), nums, 0);
return list;
}
private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){
list.add(new ArrayList<>(tempList));
for(int i = start; i < nums.length; i++){
tempList.add(nums[i]);
backtrack(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
上一篇: Spring中的@Bean注解
下一篇: 回溯法之排列组合