简要介绍:
回溯法可以系统的搜索一个问题的所有解或任意解,在问题的解空间树中,按照深度优先搜索的策略,从根节点出发搜索解空间树。开始节点为活节点,同时也是当前的扩展节点。在当前的扩展节点处向纵深方向移动,此时这个节点为新的活节点。如果在当前的扩展节点处不能向纵深方向移动,那么此节点为死节点,此时,节点应往回移动,移动至最近的活节点处。
以下的三个问题都是用回溯的方法来解决的,其算法的框架基本相同。回溯法常用来解决的问题有子集问题和排列树问题,这两个问题在以下解答中均有提及。
问题1:
描述:给定一个整型数组,其中的整数均不相同,返回其所有的子集。结果中不能含有重复的子集。例如:
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;
}
public void backtrack(List<List<Integer>> l,ArrayList<Integer> al,int[] nums,int start){
l.add(new ArrayList<>(al));
for(int i=start;i<nums.length;i++){
al.add(nums[i]);
backtrack(l,al,nums,i+1);
al.remove(al.size()-1);
}
}
}
问题2:
描述:组合问题。给定一个整型数组,其中的整数均不相同,返回所有不同的组合。例如:
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>> l=new ArrayList<>();
backtrack(nums,l,new ArrayList<Integer>());
return l;
}
public void backtrack(int[] nums,List<List<Integer>> l,List<Integer> al){
if(al.size()==nums.length){
l.add(new ArrayList<Integer>(al));
}else{
for(int i=0;i<nums.length;i++){
if(al.contains(nums[i])){
continue;
}
al.add(nums[i]);
backtrack(nums,l,al);
al.remove(al.size()-1);
}
}
}
}
问题三
描述:给定一个整型数组和目标整数,求出数组中数的组合(数组中的数可以重复使用),使得这些数之和为目标数。例如:
Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[7],
[2,2,3]
]
解法:
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> l=new ArrayList<>();
backtrack(l,new ArrayList<Integer>(),candidates,target,0);
return l;
}
public void backtrack(List<List<Integer>> l,List<Integer> al,int[] cand,int target,int start){
if(sum(al)==target){
l.add(new ArrayList<>(al));
}
for(int i=start;i<cand.length;i++){
if(sum(al)+cand[i]>target){
continue;
}
al.add(cand[i]);
backtrack(l,al,cand,target,i);
al.remove(al.size()-1);
}
}
public int sum(List<Integer> al){
int sum=0;
for(int i=0;i<al.size();i++){
sum+=al.get(i);
}
return sum;
}