您的位置:首页 > 产品设计 > UI/UE

LeetCode OJ - N-Queens 回溯法

2014-04-27 19:30 447 查看
寻找问题解的一个方法,可以采用列出所有候选解,检查完所有候选解即可得到需要的解。

问题:其中的问题在于,候选解数量很庞大时,采用遍历搜索耗费的时间巨大。

解决:采用不同的筛选方法,减小问题的规模,从而缩短搜索的时间。

方法:回溯法、分支界定法

——————————————————————————————————————————

回溯算法 http://blog.csdn.net/pinkrobin/article/details/5378702
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.



Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 
'Q'
 and 
'.'
 both
indicate a queen and an empty space respectively.

For example,

There exist two distinct solutions to the 4-queens puzzle:
[
[".Q..",  // Solution 1
"...Q",
"Q...",
"..Q."],

["..Q.",  // Solution 2
"Q...",
"...Q",
".Q.."]
]

思考:

1.总体思路

2.采用什么数据结构

3.需要解决的问题

4.采用什么程序结构

       假设棋盘式NxN的二维数组,首先在第一行放置一个Q,接着在第二行放,直到放到第N行,若放置完成则表示找到一种解决方案。如何遍历所有解决方案呢,可以采用递归的方式,使用深度遍历找出所有方案(调用Q(0))。

        应该采用什么数据结构呢,若采用二维数组Q

,需要解决A.该行是否有元素 B.该列是否有元素 C.该对角线上是否有元素,这几个应该好解决。若现在要在(row, col)这个点上检查是否可以放皇后,row行没还没放故只用判断row行之前的情况,判断如下:
bool flag = false; //不能放置皇后
for(i = row-1; i >= 1; i--) {
//每行应该判断三个点:Q[i][col+i-row]、 Q[i][col]、 Q[i][col-i+row]
// 可通过判断行列的变化情况找到这三个点
if( Q[i][col+i-row] == 0 && Q[i][col] == 0 && Q[i][col-i+row] ) {
flag = true;
Q[row][col] = 1;
}
}

        如果要记录下所有结果呢,也就是所有的二维表结果,应该怎么设计呢?  因为深度遍历每一次从根节点,访问到叶子节点,本身就是一种解决方案,记录该方案即可。采用输出表示记录该方案。

bool isPutQueen(int row, int col) {
bool flag = false;
for(int i = row - 1; i >= 1; i--) {
if(!Q[i][col+i-row] && !Q[i][col] && !Q[i][col-i+row]) {
flag = true;
break;
}
}
return flag;
}

void NQueen(int row) {
if(row == N) {
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= N; j++) {
cout << Q[i][j] << " ";
Q[i][j] = 0;
}
cout << endl;
}
cout << endl;
return ;
} else {
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= N; j++)//回溯法的精髓,记录了前面row-1行的情况
Q[row][j] = 0;
if(isPutQueen(row, i)) {
NQueen(row++);
}
}
}
}
#define N 16
int Q[N + 1][N + 1];

int main() {
InitQueen();
NQueen(1);
return 0;
}


非递归方式:

优化存储结构:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: