LeetCode

题目:

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) 递归,每次递归时把横竖斜方向的位置设置为"Forbidden"区域

package recursion;

import java.util.ArrayList;
import java.util.List;

public class NQueens {

    public List<List<String>> solveNQueens(int n) {
        char[][] board = new char[n][n];
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                board[i][j] = '.';
            }
        }
        List<List<String>> res = new ArrayList<List<String>>();
        solve(res, 0, board, n);
        return res;
    }
    
    private void solve(List<List<String>> res, int row, char[][] board, int n) {
        if (row >= n) {
            List<String> record = new ArrayList<String>();
            for (int i = 0; i < n; ++i) {
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < n; ++j) {
                    if (board[i][j] != 'Q')
                        board[i][j] = '.';
                    sb.append(board[i][j]);
                }
                record.add(sb.toString());
            }            
            
            res.add(record);
            return;
        }
        
        for (int i = 0; i < n; ++i) {
            if (board[row][i] == '.') {
                char[][] cpyBoard = copyBoard(board, n);
                setForbiddenArea(cpyBoard, row, i, n);
                solve(res, row + 1, cpyBoard, n);
            }
        }
    }
    
    private void setForbiddenArea(char[][] board, int i, int j, int n) {
        // Rows and columns
        for (int k = 0; k < n; ++k) {
            board[i][k] = 'F';
            board[k][j] = 'F';
        }
        // Diagonal
        for (int k = 1 - n; k <= n - 1; ++k) {
               if (i + k >= 0 && i + k < n && j + k >= 0 && j + k < n)
                   board[i + k][j + k] = 'F';
               if (i + k >= 0 && i + k < n && j - k >= 0 && j - k < n)
                   board[i + k][j - k] = 'F';
        }
        board[i][j] = 'Q';
    }
    
    private char[][] copyBoard(char[][] board, int n) {
        char[][] cpyBoard = new char[n][n];
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j)
                cpyBoard[i][j] = board[i][j];
        }
        return cpyBoard;
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        NQueens n = new NQueens();
        List<List<String>> res = n.solveNQueens(4);
        for (List<String> subRes : res) {
            for (String s : subRes)
                System.out.print(s + "	");
            System.out.println("
");
        }
    }

}

2) 用一个一维数组来存储每行对应的Q的位置,i代表第i行,rows[i]代表Q的位置。

package recursion;

import java.util.ArrayList;
import java.util.List;

public class NQueens {

    public List<List<String>> solveNQueens(int n) {
        List<List<String>> res = new ArrayList<List<String>>();
        int[] positions = new int[n];
        solve(positions, res, 0, n);
        return res;
    }
    
    private void solve(int[] positions, List<List<String>> res, int row, int n) {
        if (row == n) {
            List<String> record = new ArrayList<String>();
            for (int i = 0; i < n; ++i) {                
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < n; ++j)
                    sb.append('.');
                sb.setCharAt(positions[i], 'Q');
                record.add(sb.toString());
            }
            res.add(record);
        } else {
            for (int i = 0; i < n; ++i) {
                if (isValid(positions, row, i)) {
                    positions[row] = i;
                    solve(positions, res, row + 1, n);
                }
            }
        }
    }
    
    private boolean isValid(int[] positions, int row, int candidate) {
        for (int i = 0; i < row; ++i) {
            if (positions[i] == candidate || Math.abs(i - row) == Math.abs(positions[i] - candidate))
                return false;
        }
        return true;
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        NQueens n = new NQueens();
        List<List<String>> res = n.solveNQueens(4);
        for (List<String> subRes : res) {
            for (String s : subRes)
                System.out.print(s + "	");
            System.out.println("
");
        }
    }

}
原文地址:https://www.cnblogs.com/null00/p/5078347.html