问题:
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.."] ]
说明:
- 任意两个皇后不在同一行,不在同一列,不在同一对角线。
- 返回所有满足条件的皇后布局
- 考虑边界条件,当n = 1的情况。
分析:
- 同行同列的情况,我们可以使用个技巧规避掉,即定义一个数组,下标代表行,下标对应的元素值代表所在的列,初始的时候,我们将皇后放在主对角线上,即数组的每个元素初始化为其下标。这样就得到了一串数,如 4皇后的 0 1 2 3。
- 接下来的事情就是对其进行全排列,并检查每种排列是否符合要求,即检查是否在同一对角线上,在同一对角线上,就是在同一直线上,就是斜率相同,对于方针就是斜率为+1,-1,就是 |(y1- y2) | = | x1 - x2 |。
- 对于全排列,在问题库里有,见 permutation 。
实现:
bool nextPermutation(vector<int> &num) { int i = num.size() - 1; while (i >= 1) { if(num[i] > num[i - 1]) { --i; int ii = num.size() - 1; while (ii > i && num[ii] <= num[i]) --ii; if(ii > i) { swap(num[i], num[ii]); reverse(num.begin() + i + 1, num.end()); return true; } } else --i; } return false; } bool check(vector<int> &grids) { int len = grids.size(); for (int i = 0; i < len; ++i) for (int j = i + 1; j < len; ++j) { if(abs(i - j) == abs(grids[i] - grids[j])) return false; } return true; } vector<vector<string> > solveNQueens(int n) { vector<vector<string> > re; if(n < 1) return re; if(n == 1) return vector<vector<string> >(1,vector<string>(1,"Q")); vector<int> grids(n,0); for (int i = 0; i < n; ++i) { grids[i] = i; } while (nextPermutation(grids)) { if(check(grids)) { vector<string> one_solve; for(int i = 0; i < n; ++i) { string line(n,'.'); line[grids[i]] = 'Q'; one_solve.push_back(line); } re.push_back(one_solve); } } return re; }
说明:何海涛 ,回溯版本
【leetcode】N-queens,布布扣,bubuko.com
时间: 2024-12-18 17:09:04