LeetCode刷题笔记-51

LeetCode-51. N-Queens(Hard):

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.

Example:

Input: 4
Output: [
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.

大神解法:

这道题是经典的八皇后问题,要用回溯算法做,我尝试解了一下发现有点复杂,不知道有没有什么套路于是直接找了网上的答案,这段答案速度和空间都是最优的,于是拿来详细分析一下。

首先查了一下回溯和动态规划、递归的异同,发现他们其实特别相似,是近亲,不同点是回溯的子结构不一定是最优的,是一种以尝试为思想的解法,这就需要算法能处理万一子结构走不通还要回来的状态恢复问题。

看一下答案最下面的for循环,发现递归求解子问题之后立刻就恢复了之前修改过的状态,这可能就是回溯算法的精髓吧。

至于程序开头定义的三个boolean数组没太理解为什么,只知道是为了标记各个位置的横竖斜方向有没有王后的,可能他这种方法效率比较高吧。。。

class Solution {
    public List<List<String>> solveNQueens(int n) {
        boolean[] col = new boolean[n];
        boolean[] diagnolCol = new boolean[2*n-1];
        boolean[] diagnolRol = new boolean[2*n-1];
        
        char[][] game = new char[n][n];
        for(int i = 0; i < game.length; i++) {
            Arrays.fill(game[i], '.');
        }
        
        List<List<String>> res = new ArrayList<>();
        
        solveNQueens(col, diagnolCol, diagnolRol, game, 0, n, res);
        return res;
    }
    
    private void solveNQueens(boolean[] col, boolean[] diagnolCol, boolean[] diagnolRol, char[][] game, int row, int n, List<List<String>> res) {
        if(row == n) {
            List<String> sol = new ArrayList<>();
            for(char[] line : game) {
                sol.add(new String(line));
            }
            res.add(sol);
            return;
        }
        for(int i = 0; i < n; i++) {
            //!col !diagnolCol[i+j] !diagnolRol[n-1 + row-i]
            if(col[i] || diagnolCol[i+row] || diagnolRol[n-1 + row-i]) {
                continue;
            }
            game[row][i] = 'Q';
            col[i] = true;
            diagnolCol[i+row] = true;
            diagnolRol[n-1 + row-i] = true;
            solveNQueens(col, diagnolCol, diagnolRol, game, row+1, n, res);
            col[i] = false;
            diagnolCol[i+row] = false;
            diagnolRol[n-1 + row-i] = false;
            game[row][i] = '.';
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值