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

Solution:

 

We will use a backtracking algorithm For each row, the column where we want to put the queen is based on checking that it does not violate the required condition

1, For this, we need to store the column of the queen in each row as soon as we have finalized it. Let ColumnForRow[] be the array which stores the column number for each row

2, The checks that are required for the three given conditions are:
» On same Column : ColumnForRow[i] == ColumnForRow[j]
» On same Diagonal: abs( ColumnForRow[i] - ColumnForRow[j] ) == abs( i - j )

private int[] col4Row;
private char[] placement;
public List<String[]> solveNQueens(int n) {
    col4Row = new int[n];
    placement = new char[n];
    Arrays.fill(placement, '.');
    List<String[]> result = new ArrayList<>();
    placeQueen(result, 0, n);
    return result;
}

public void placeQueen(List<String[]> result, int row, int n) {
    if(row == n) {
        String[] solution = new String[n];
        for(int i=0; i<col4Row.length; i++) {
            int col = col4Row[i];
            placement[col] = 'Q';
            solution[i] = new String(placement);
            placement[col] = '.';
        }
        result.add(solution);
    } else {
        for(int i=0; i<n; i++) {
            col4Row[row] = i;
            if(check(row)) {
                placeQueen(result, row+1, n);
            }
        }
    }
}

public boolean check(int row) {
    for(int i=0; i<row; i++) {
        int diff = Math.abs(col4Row[i] - col4Row[row]);
        if(diff == 0 || diff == row - i) return false;
    }
    return true;
}

 

C++的版本1:

vector<vector<string>> solveNQueens(int n) {
    vector<vector<string>> res;
    vector<int> col4Row(n);
    solve(res, col4Row, 0);
    return res;
}

void solve(vector<vector<string>>& res, vector<int>& col4Row, int row) {
    int n = col4Row.size();
    if(row == n) {
        vector<string> v;
        for(auto col: col4Row) {
            string s(n, '.');
            s[col] = 'Q';
            v.push_back(s);
        }
        res.push_back(v);
        return;
    }
    for(int i=0; i<n; i++) {
        col4Row[row] = i;
        if(check(col4Row, row)) {
            solve(res, col4Row, row+1);
        }
    }
}

bool check(vector<int>& col4Row, int row) {
    int col = col4Row[row];
    for(int i=0; i<row; i++) {
        int diff = abs(col4Row[i] - col4Row[row]);
        if(!diff || diff == row-i) return false;
    }
    return true;
}

 

C++的版本2,使用Lamda表达式:

vector<vector<string>> solveNQueens(int n) {
    vector<vector<string>> res;
    vector<int> col4Row(n);
    
    auto check = [&](int row) {
        int col = col4Row[row];
        for(int i=0; i<row; i++) {
            int diff = abs(col4Row[i] - col4Row[row]);
            if(!diff || diff == row-i) return false;
        }
        return true;
    };
    
    function<void(int)> solve = [&](int row){
        if(row == n) {
            vector<string> v;
            for(auto col: col4Row) {
                string s(n, '.');
                s[col] = 'Q';
                v.push_back(s);
            }
            res.push_back(v);
            return;
        }
        for(int i=0; i<n; i++) {
            col4Row[row] = i;
            if(check(row)) {
                solve(row+1);
            }
        }
    };
    
    solve(0);
    return res;
}

 

你可能感兴趣的:(LeetCode)