Home > Enterprise >  Adding all solutions of N Queen Problem to an arrayList
Adding all solutions of N Queen Problem to an arrayList

Time:09-17

The n-queens puzzle is the problem of placing n queens on a (n×n) chessboard such that no two queens can attack each other.

I used backtracking to solve the problem. But I ran in a strange issue.

Below is the code I wrote:

import java.util.ArrayList;

public class NQueenProblem {

    static ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>();

    static ArrayList<ArrayList<Integer>> nQueen(int n) {

        ArrayList<Integer> positions = new ArrayList<Integer>();
        //boolean[][] placed = new boolean[n][n];
        solveNQueenRec(n, 0, new boolean[n][n], positions);
        //for dubugging purpose. This prints empty arrays. not able to understand why?
        for (ArrayList<Integer> list : ans)
            System.out.println(list);
        return ans;
    }

    static void solveNQueenRec(int n, int col, boolean[][] placed, ArrayList<Integer> positions) {
        if (col == n) {
            //for debugging process
            System.out.println("Adding "   positions);
            ans.add(positions);
            System.out.println("Added "   positions);
        }
        for (int row = 0; row < n && col < n; row  ) {
            if (isSafe(row, col, placed, n)) {
                placed[row][col] = true;
                positions.add(row   1);
                solveNQueenRec(n, col   1, placed, positions);
                placed[row][col] = false;
                positions.remove(positions.size() - 1);
            }
        }
        // return null;
    }

    private static boolean isSafe(int row, int col, boolean[][] placed, int n) {
        boolean safe = true;
        // checking if exists in same row
        for (int i = 0; i < col; i  ) {
            if (placed[row][i])
                safe = false;
        }
        // checking for upper diagonal
        for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
            if (placed[i][j])
                safe = false;
        }
        // checking for lower diagonal
        for (int i = row, j = col; i < n && j >= 0; i  , j--) {
            if (placed[i][j])
                safe = false;
        }
        return safe;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        nQueen(4);

    }

}

What I am not able to understand is why my ans is empty when I could see in logs list being added to my ans. Am I doing some silly mistake. Please help me with the issue. If possible please help me with links to understand the issue and how could I avoid these issues in future.

CodePudding user response:

I think you believe that when the JVM executes

   ans.add(positions);

that it is taking a copy of the current state of positions and adding it to the list. It isn't, it is doing exactly what the code says: adding a reference to an ArrayList to ans.

All the items in ans are references to the same ArrayList, and that array list is empty when you print out ans.

CodePudding user response:

ans.add(positions);

is your "problem". You are just adding to ans a reference to the list positions. Thus ans is full of references to the same positions list. As you modify positions several time after insertion, until emptied it, at the end ans is full of n references (n being the number of solutions found) the same positions list that is empty at the end.

What you need is to insert a copy of the current positions list at the time a solution is found:

ans.add(new ArrayList<Integer>(positions));

copy is obtained by constructing a new list with the exact content of the original one.

CodePudding user response:

Add this checking make sure it is greater than zero, then print out the answer. Moreover, add the print queen function, your will see the answer clearly. If this solve your problem, please make as answer.

for (ArrayList<Integer> list : ans) {
    if (list.size() > 0)
        System.out.println(list);
}

static void solveNQueenRec(int n, int col, boolean[][] placed, ArrayList<Integer> positions) {
    if (col == n) 
        printQueens(positions);
    
    for (int row = 0; row < n && col < n; row  ) {
        if (isSafe(row, col, placed, n)) {
            placed[row][col] = true;
            positions.add(row   1);
            solveNQueenRec(n, col   1, placed, positions);
            placed[row][col] = false;
            positions.remove(positions.size() - 1);
        }
    }
    // return null;
}


public static void printQueens(ArrayList<Integer> q) {
    int n = q.size();
    for (int i = 0; i < n; i  ) {
        for (int j = 1; j <= n; j  ) {
            if (q.get(i) == j) 
                System.out.print("Q ");
            else           
                System.out.print("* ");
        }
        System.out.println();
    }  
    System.out.println();
}

solution to 4-queens sample:
* Q * * 
* * * Q 
Q * * * 
* * Q * 

* * Q * 
Q * * * 
* * * Q 
* Q * *
  • Related