这是我参与更文挑战的第26天,活动详情查看: 更文挑战
回溯算法
回溯算法是一种纯暴力递归搜索算法,也可以说成是深度优先搜索算法。
回溯法采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现,现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案。回溯法通常用最简单的递归方法来实现,在反复重复上述的步骤后可能出现两种情况:
- 找到一个可能存在的正确的答案
- 在尝试了所有可能的分步方法后宣告该问题没有答案
框架模板
回溯算法的实现过程就是一颗多叉树的遍历搜索过程。其中涉及到的状态我们可以归纳为:
- List<List> res:存储最终返回的结果
- int depth:当前遍历的层数
- int[] nums:给定的已知数组
- boolean[] used:标识当前结点是否被访问过
- Qeque path:存储从根结点到目前结点之间的路径结点
List<List<Integer>> res;
void backTracking(路径,选择列表){
if(满足约束条件){
res.add(路径);
return;
}
for(选择:选择列表){
做选择;
backTracking(路径:选择列表);
撤销选择;
}
}
实例演示
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
输入:nums = [1,2,3]
输出:[[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>> res=new ArrayList<>();
Deque<Integer> path=new ArrayDeque<Integer>();
boolean[] used=new boolean[nums.length];
backTracking(nums,0,res,path,used);
return res;
}
public void backTracking(int[] nums,int depth, List<List<Integer>> res, Deque<Integer> path,boolean[] used){
if(nums.length==depth){
res.add(new ArrayList<>(path));
return;
}
for(int i=0;i<nums.length;i++){
if(!used[i]){
path.push(nums[i]);
used[i]=true;
backTracking(nums,depth+1,res,path,used);
used[i]=false;
path.removeFirst();
}
}
}
}