回溯题集
题一:括号生成
思路:DFS遍历,在匹配的过程中,剩余未使用右括号数一定比剩余的左括号数多(等于也行),只要满足这个条件,就一定保证不会出现无效的匹配
代码:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<String> generateParenthesis(int n) {
List<String> res = new ArrayList<>();
if (n == 0) {
return res;
}
dfs("", n, n, res);
return res;
}
private void dfs(String curStr, int left, int right, List<String> res) {
if (left == 0 && right == 0) {
res.add(curStr);
return;
}
if (left > right) {
return;
}
if (left > 0) {
dfs(curStr + "(", left - 1, right, res);
}
if (right > 0) {
dfs(curStr + ")", left, right - 1, res);
}
}
}
题二:组合总数
思路 深度优先遍历,注意向右深入的时候,可以再次包含当前位置的元素,即非严格向右深入。
回溯的逻辑:对于当前位置所有可以选择的元素:(1)选择一个(2)深入(3)撤销上一次的选择,进入下一次循环重新执行(1)
代码:
class Solution {
List<List<Integer>> res=new LinkedList();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
//如何不重复选取
//选一半发现接下来选不了怎么办
Deque<Integer> path=new LinkedList();
backtrace(candidates,0,target,path);
return res;
}
/*
left:剩下待匹配
path:当前路径
start 出发的位置
*/
public void backtrace(int[]candidates,int start, int left,Deque<Integer> path){
//失败的递归出口
if(left<0)return;
//成功的递归出口
if(left==0){
//匹配成功
res.add(new LinkedList(path));
return;
}
/*这个for循环表示的含义:
1.当前位置可以选的要都选一次
2.从上一轮的位置开始往后选,不能往前选(防止223 与 322这种重复)
*/
for(int i=start;i<candidates.length;i++){
path.offerLast(candidates[i]);
//从i开始回溯,做到可以重复使用candidates[i]
backtrace(candidates,i,left-candidates[i],path);
path.pollLast();
}
}
}
题三:全排列
这是一道排列树的模版题,类似于工作调度,当然了,工作调度可以剪枝。
class Solution {
List<List<Integer>> list =new ArrayList();
public List<List<Integer>> permute(int[] nums) {
dfs(nums,0);
return list;
}
private void dfs(int[] nums,int depth){
if(depth==nums.length-1){
//数组怎么转为list存下来
// ArrayList<Integer> temp=new ArrayList<Integer>(Arrays.asList(nums));
List<Integer> intList= Arrays.stream(nums).boxed().collect(Collectors.toList());
list.add(intList);
}else{
for(int i=depth;i<nums.length;i++){
swap(nums,i,depth);
dfs(nums,depth+1);
swap(nums,i,depth);
}
}
}
private void swap(int[]a,int indexl,int indexr){
int temp=a[indexl];
a[indexl]=a[indexr];
a[indexr]=temp;
}
}