I'm working on the N-Queens problem on LeetCode, which stipulates that the return type for the main method is a List<List<String>>
. I thought that if I made a global variable that was a List<List<String>>
, then in main instantiated it as an ArrayList<ArrayList<String>>
, I would be able to return as the proper type, but when I try to instantiate it gives the error: "Line 12: error: incompatible types: ArrayList<ArrayList<StringBuilder>>
cannot be converted to ArrayList<ArrayList<String>>
".
I was also under the impression that, because ArrayList implements List, you could return an instance of an ArrayList as a List, but when I make the global variable an ArrayList it gives the following error: "Line 15: error: incompatible types: ArrayList<ArrayList<String>>
cannot be converted to List<List<String>>
". Printing out the boards that are considered valid I know I'm getting the right combinations, but this last detail has really frustrated me and I would very much appreciate any explanation for why I'm getting these errors. Thanks!
class Solution {
ArrayList<Integer> colsUsed;
ArrayList<Integer> leftDiagsUsed;
ArrayList<Integer> rightDiagsUsed;
ArrayList<ArrayList<String>> solutions;
public List<List<String>> solveNQueens(int n) {
colsUsed = new ArrayList<Integer>();
leftDiagsUsed = new ArrayList<Integer>();
rightDiagsUsed = new ArrayList<Integer>();
ArrayList<StringBuilder> board = createBoard(n);
solutions = new ArrayList<ArrayList<String>>();
return solutions;
}
public void iterateBoards(ArrayList<StringBuilder> board, int row, int n){
if (row >= n){
printBoard(board);
addBoard(board);
return;
}
for (int col = 0; col < n; col++){
if (!colsUsed.contains(col) && !leftDiagsUsed.contains(row - col) && !rightDiagsUsed.contains(row + col)){
colsUsed.add(col);
leftDiagsUsed.add(row - col);
rightDiagsUsed.add(row + col);
board.get(row).setCharAt(col, 'Q');
iterateBoards(board, row + 1, n);
colsUsed.remove(new Integer(col));
leftDiagsUsed.remove(new Integer(row - col));
rightDiagsUsed.remove(new Integer(row + col));
board.get(row).setCharAt(col, '.');
}
}
}
public ArrayList<StringBuilder> createBoard(int n){
StringBuilder row = new StringBuilder();
ArrayList<StringBuilder> board = new ArrayList<StringBuilder>(n);
for (int col = 0; col < n; col++){
row.append(".");
}
for (int currRow = 0; currRow < n; currRow++){
board.add(new StringBuilder(row.toString()));
}
return board;
}
public void addBoard(ArrayList<StringBuilder> board){
List<String> newBoard = new ArrayList<String>();
for (int i = 0; i < board.size(); i++){
newBoard.add(board.get(i).toString());
}
solutions.add(newBoard);
}
public void printBoard(ArrayList<StringBuilder> board){
for (int i = 0; i < board.size(); i++){
StringBuilder curr = board.get(i);
System.out.println(curr.toString());
}
System.out.println();
}
}
Change all variable declarations to use only the List
interface. It's a good practice to use the widest possible type that you need in the declaration - for java.util collections, that's almost always the interface.
The fact that you chose to use an ArrayList (rather than, for example, a LinkedList) is an implementation detail that has no impact on the rest of your code.
class Solution {
List<Integer> colsUsed;
List<Integer> leftDiagsUsed;
List<Integer> rightDiagsUsed;
List<List<String>> solutions;
public List<List<String>> solveNQueens(int n) {
// [...]
solutions = new ArrayList<List<String>>();