From charlesreid1

8 queens problem solution in Java:

import java.util.LinkedList;
import java.util.Arrays;

public class NQueens {


    ///////////////////////////////////////////////////
    // main
    //
    public static void main(String[] args) {
        SolutionSaver s = new SolutionSaver();
        Board b = new Board(8);
        explore(b,0);
		  System.out.printf("Found %d solutions\n ", SolutionSaver.nSolutions() );
    }
    //
    ///////////////////////////////////////////////////


    /// Placing queens, column-by-column; place the queen in column col.
    public static void explore(Board b, int col) {

        if(col >= b.size() ) {

            // We have reached the end.
            // No conflicts so far means no conflicts period.

            // Save solution in a static class, no instantiation overhead
            String serial = b.toString();
            SolutionSaver.saveSolution(serial);

		} else {

            // The legalRows() method is a little bit of magic.
            // It returns an array of valid rows on which to place the col^th queen.
            for(Integer row : b.legalRows(col) ) { // important question: is this called each time in the loop?
                                                   // (do i need to make a copy outside the loop?)
                b.place(row,col);
                explore(b,col+1);
                b.remove(row,col);

            }
        }// done with base/recursive cases
    }

}

class Board {

    int[] queens;                   // Array to store where queens have been placed.
                                    // The queens array has a length of board_size.
                                    // Each element stores an integer between 1 and N.
                                    // That indicates the row/column.

    int[] occupiedrows;             // Array to mark occupied rows.
                                    // This is how we check for horizontal attacks.

    int board_size;                 // Size of our problem

    public Board(int size) {
        this.board_size = size;
        this.queens = new int[size];
        this.occupiedrows = new int[size];
    }

    public int size(){
        return this.board_size;
    }

    public String toString() {
        return Arrays.toString(this.queens);
    }

    public void place(int row, int col) {
        if( col < this.queens.length && row < this.occupiedrows.length ) {
            this.queens[col] = row;
            this.occupiedrows[row] = 1;
        }
    }

    public void remove(int row, int col) {
        if( col < this.queens.length && row < this.occupiedrows.length ) {
            this.queens[col] = 0;
            this.occupiedrows[row] = 0;
        }
    }

    public LinkedList<Integer> legalRows( int col ) {

        LinkedList<Integer> legalList = new LinkedList<Integer>();

        // 1. Mark invalid squares on diagonals of already-placed queens
        //
        // 2. For this column, loop over each row where it's legal to place a queen,
        //    and run backtracking on that choice. Then unmake the choice and keep going.

        // Store invalid rows on other queens' diagonals
        int[] diag = new int[size()];

        // Loop over all of the queens already placed (col-1)
        for(int k = 0; k <= (col-1); k++ ) {

            // We're trying to place the next queen on col.
            // Find which squares on col are on the diagonal of this queen,
            // and mark them as imposisble.

            // Lower right diagonal
            int ix1 = this.queens[k] + col - k;
            if(ix1 >= 0 && ix1 < size() ) {
                diag[ix1] = 1;
            }

            // Upper right diagonal
            int ix2 = this.queens[k] - col + k;
            if(ix2 >= 0 && ix2 < size() ) {
                diag[ix2] = 1;
            }

        }

        for (int row = 0; row < size(); row++) {

            // If this row is legal, add it to the list
            boolean legal = diag[row]==0 && this.occupiedrows[row]==0;
            if(legal) {
                legalList.add(row);
            }

        }

        return legalList;
    }
}


class SolutionSaver {
    private static LinkedList<String> solutions;

    public SolutionSaver() {
        SolutionSaver.solutions = new LinkedList<String>();
    }

    public static void saveSolution(String serialized) {
        SolutionSaver.solutions.add(serialized);
    }

    public static void printSolutions() {
        int c = 0;
        for( String sol : solutions ) {
            System.out.printf("Solution %d: %s \n", c, sol);
        }
    }
    public static int nSolutions() {
        return solutions.size();
    }
}