回溯思想简单理解
问题说明
给定一个正整数数组nums,为方便理解,假定数组中不存在重复的整数。
列出这些整数的全排列
如:nums={1,2,3},那么答案为:
{{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}}
问题解释
1. 我们可以直接穷举出所有的排列可能,这也是回溯算法的核心思想,但一般回溯
都会通过剪枝来减少不合理的可能值
2. 用树结构来理解回溯的思想
解空间树
1. 我们不难在脑海中构建这样的一颗树结构,事实上,它对于所有回溯问题都适用
我们构建一个已选择路径的数组track[],它表示已选择的三个数字,也就是已选择的路径,
例如:选择了{1,2},表示第一步选择了数字1,第二步选择了数字2,那么最后一次做选择
时,我们把已选择的路径从nums剔除出去,第三步也就只能选择数字3
3. 一套适合回溯问题的模板
void backtrack(){
if 满足结束条件 (track数组已满)
存储结果..return
for 选择 in 选择列表 (nums长度)
做选择(加入路径)
递归下一层
撤销选择
}
我们用一个List<List<Integer>>存放所有结果值,LinkedList<Integer>存放路径
获得全排列主要代码
public static void backtrack(int[] nums,LinkedList<Integer> track){
if(track.size()==nums.length){
res.add(new LinkedList(track));
return;
}
for(int i=0;i<nums.length;i++){
if(track.contains(nums[i]))
continue;
track.add(nums[i]);
backtrack(nums,track);
track.removeLast();
}
}