51. N皇后
完成
思路:
如何用回溯法搜索二维棋盘是这道题目和之前不一样的地方,也是题目的难点。
在树形结构中,同层取同一行棋盘的不同列遍历。每递归一次就往下遍历一行。
代码
class Solution {List<List<String>> res = new ArrayList<>();// 棋盘char[][] chessboard;public List<List<String>> solveNQueens(int n) {chessboard = new char[n][n];// 初始化棋盘for (char[] c : chessboard) {Arrays.fill(c, '.');}backTrack(n, 0);return res;}public void backTrack(int n, int row) {if (row == n) {// 把合法的棋盘情况添加进去res.add(Array2List(chessboard));return;}// 同层遍历列for (int col = 0;col < n; ++col) {// 判断是否存在同行同列同斜线的棋子if (isValid (row, col, n, chessboard)) {chessboard[row][col] = 'Q';backTrack(n, row+1);chessboard[row][col] = '.';}}}public List Array2List(char[][] chessboard) {List<String> list = new ArrayList<>();for (char[] c : chessboard) {list.add(String.copyValueOf(c));}return list;}public boolean isValid(int row, int col, int n, char[][] chessboard) {// 检查列for (int i=0; i<row; ++i) { // 相当于剪枝if (chessboard[i][col] == 'Q') {return false;}}// 检查45度对角线for (int i=row-1, j=col-1; i>=0 && j>=0; i--, j--) {if (chessboard[i][j] == 'Q') {return false;}}// 检查135度对角线for (int i=row-1, j=col+1; i>=0 && j<=n-1; i--, j++) {if (chessboard[i][j] == 'Q') {return false;}}return true;}
}
总结
回溯法就是暴力搜索,并不是什么高效的算法,最多再剪枝一下。
回溯算法能解决如下问题:
- 组合问题:N个数里面按一定规则找出k个数的集合
- 排列问题:N个数按一定规则全排列,有几种排列方式
- 切割问题:一个字符串按一定规则有几种切割方式
- 子集问题:一个N个数的集合里有多少符合条件的子集
- 棋盘问题:N皇后,解数独等等