LeetCode刷题笔录N-Queens

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.."]
]

很经典的题了,在CTCI上面有道一模一样的。

以8x8棋盘为例。由于放queen的顺序与结果无关,因此假设棋子是按照从row(0)到row(7)的顺序进行摆放的。这样在处理最后一行时有8种可能的摆放方法:

ways to place 8 queens on a 8x8 board=

ways to place 8 queens on a 8x8 board with a queen at (7,0)+

ways to place 8 queens on a 8x8 board with a queen at (7,1)+

...

ways to place 8 queens on a 8x8 board with a queen at (7,7)

上面的每一种摆放方法又可以继续分为更多的情况,比如以最后一行放在(7,0)为例,

ways to place 8 queens on a 8x8 board with a queen at (7,0) = 

ways to place 8 queens on a 8x8 board with a queen at (7,0) and another at (6,1)+

....

ways to place 8 queens on a 8x8 board with a queen at (7,0) and another at (6,7)

这样子下去就可以一行一行地递归来得到结果了。


public class Solution {
    public List<String[]> solveNQueens(int n) {
        List<String[]> result = new ArrayList<String[]>();
        String[] solution = new String[n];
        placeQueens(0, n, result, solution);
        return result;
    }
    
    public void placeQueens(int row, int n, List<String[]> result, String[] solution){
        //found one solution
        if(row == n){
            result.add(Arrays.copyOfRange(solution, 0, n));
        }
        else{
            for(int col = 0; col < n; col++){
                if(checkValid(row, col, solution)){
                    addOneRow(solution, row, col, n);
                    placeQueens(row + 1, n, result, solution);
                }
            }
        }
    }
    
    public boolean checkValid(int row, int col, String[] solution){
        //have to check all the previous rows if violating rules with the current row
        for(int i = 0; i < row; i++){
            String line = solution[i];
            //j is the column index of this row that the queen lies
            int j = line.indexOf("Q");
            
            //check if they are in the same column
            if(col == j)
                return false;
            
            //check if they are in the same diagnol
            int colDiff = Math.abs(j - col);
            int rowDiff = row - i;
            if(colDiff == rowDiff)
                return false;
            
        }
        return true;
    }
    
    public void addOneRow(String[] solution, int row, int col, int n){
        StringBuilder builder = new StringBuilder();
        for(int i = 0; i < col; i++){
            builder.append(".");
        }
        builder.append("Q");
        for(int i = col + 1; i < n; i++){
            builder.append(".");
        }
        solution[row] = builder.toString();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值