全排列也是回溯的一种常见题型,也可以用回溯模板来写,用一个used数组标志元素是否使用过,但这种交换的写法更常见,常用于需要检查满足条件的排列
class Solution {
List<List<Integer>> res=new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
backtracking(nums,0,nums.length-1);
return res;
}
public void backtracking(int[] nums,int start,int end){
if(start==end){
List<Integer> list=new ArrayList<>();
for(int i:nums){
list.add(i);
}
res.add(list);
return;
}
for(int i=start;i<=end;i++){
swap(nums,start,i);
backtracking(nums,start+1,end);
swap(nums,start,i);
}
}
public void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
子集的问题区别就在于子集是收集每一个节点的,而不是收集满足条件的叶子节点
class Solution {
List<Integer> path=new ArrayList<>();
List<List<Integer>> res=new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backtracking(nums,0);
return res;
}
public void backtracking(int[] nums,int start){
res.add(new ArrayList<>(path));
for(int i=start;i<nums.length;i++){
path.add(nums[i]);
backtracking(nums,i+1);
path.remove(path.size()-1);
}
}
}