回溯算法
Posted xiao--ge
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回溯算法相关的知识,希望对你有一定的参考价值。
回溯算法是一种尝试搜索求解的过程,当发现当前条件已经不满足求解的条件时就返回上一次的状态——回溯。
尝试别的路径,直至求出问题的解。有很多地方都用到了回溯的思想,算是一种“通用解”。
回溯法的一般步骤:
- 确定问题的解
- 确定边界
- 确定搜索规则
- 确定解所需要的条件
代码框架
bool Search(...)
{
if(/*边界和解条件*/)
{
/*清除状态,回溯*/
return false;
}
/*状态标记*/
/*深度递归*/
Search(...);
/*得出解或者全部遍历完成后结束遍历*/
return true;
}
N皇后
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q‘ 和 ‘.‘ 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
题目来源:https://leetcode-cn.com/problems/n-queens/
参考代码:
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<string>map(n,string(n,‘.‘));
swap(this->map,map);
res.clear();
this->n=n;
dfs(0);
return res;
}
private:
vector<vector<string>>res;
vector<string>map;
int n=0;
bool isQueens(int y,int x){
int base_11= (y-x)>0?y-x:0;
int base_12= (x-y)>0?x-y:0;
int base_21= (y+x)<n?y+x:n-1;
int base_22= (y+x)<n?0:y+x-n+1;
for(int i=0;i<n;++i){
if(i!=x&&map[y][i]==‘Q‘)return false;
if(i!=y&&map[i][x]==‘Q‘)return false;
int list=base_11+i;
int line=base_12+i;
if(list>=0&&list<n&&line>=0&&line<n&&(list!=y||line!=x)){
if(map[list][line]==‘Q‘)return false;
}
list=base_21-i;
line=base_22+i;
if(list>=0&&list<n&&line>=0&&line<n&&(list!=y||line!=x)){
if(map[list][line]==‘Q‘)return false;
}
}
return true;
}
void dfs(int z){
if(z>=n){
res.push_back(map);
return;
}
for(int i=0;i<n;++i){
map[z][i]=‘Q‘;
if(isQueens(z,i))
dfs(z+1);
map[z][i]=‘.‘;
}
}
};
以上是关于回溯算法的主要内容,如果未能解决你的问题,请参考以下文章