leetcode17、77
- 回溯算法可以当作是二叉树的结构进行分析,看在叶节点的位置是什么条件收获结果
- 每个抛进去的结果都是到叶子节点的路径
以leetcode17为例:
每一层遍历的是每一个号码对应的字符串,当号码全部遍历完成就可以返回结果,所以终止条件是(index==string.length());index是层数,string是号码。
每一层的操作是遍历每个号码对应的字符串,所以操作的for循环遍历的是每个号码索引的index的每个字符,将每个字符加入路径path;在最后返回结果时将所有果实path添加进返回结果。
回溯模板
void backtracking(int index,int n,string& digits){
if(满足终止条件){
result.push_back(path);
return ;
}
char c=digits[index];
//操作
for(int i=0;i<m[c].size();i++){
path.push_back(m[c][i]);
backtracking(index+1,n;digits);
path.pop_back();//回溯
}
}
string也可以像vector一样做pop_back()和push_back()操作
在77的问题中,每层都需要传入相应的起始位置,即回溯算法参数需要多一个起始位置的索引,每一层搜索需要将这个参数加1
backtracking(int index,int n,string& digits,int startIndex)
剪枝操作:在for循环中剪去子树的量
假设x为满足条件的搜索的最大起始下标(startInex),y为已经放入路径的个数,n为搜索的数据范围,k为需要的路径长度,那么:
n+1-x+y=k;x=n+1+y-k;
for(int i=0;i<=(n+1+path.size()-k);i++){
path.push_back(i);
backtracking(index+1,n;digits);
path.pop_back();//回溯
}