반응형
문제
https://leetcode.com/problems/n-queens/description/
문제 분석
n x n 크기의 판에 Queen 들을 안전하게 놓는 방법을 구하는 문제이다.
Queen 은 가로, 세로, 대각선으로 공격을 한다.

n = 4 일 경우는 위의 두가지 방법이 존재한다.
조건에 1 <= n <= 9 로 충분히 n 이 작기 때문에 완전탐색으로 문제를 풀 수 있을 거 같다.
접근 방법
DFS 를 활용한 완전탐색으로 문제를 해결하였다.
row 당 Queen 이 하나 올 수 있기 때문에 row 를 depth 로 사용하였고 queen 을 놓을때 마다 map 에 놓을 수 없는 위치를 표시하였다.
그 후 row + 1 을 하여 재귀 호출을 하였다.
코드
import java.util.*;
class Solution {
public List<List<String>> solveNQueens(int n) {
int[][] map = new int[n][n];
List<List<String>> answer = new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();
dfs(0, new ArrayList<>(), result, map);
for(List<Integer> list : result){
List<String> strList = new ArrayList<>();
for(int idx : list){
String str = "";
for(int i=0; i<idx; i++){
str += ".";
}
str += "Q";
for(int i=idx+1; i<n; i++){
str += ".";
}
strList.add(str);
}
answer.add(strList);
}
return answer;
}
public void dfs(int row, List<Integer> cur, List<List<Integer>> result, int[][] map){
if(row == map.length){
result.add(new ArrayList<>(cur));
return;
}
for(int col = 0; col < map.length; col++){
if(map[row][col] == 0){
int[][] markingMap = mark(map, row, col);
cur.add(col);
dfs(row+1, cur, result, markingMap);
cur.remove(cur.size()-1);
}
}
}
public int[][] mark(int[][] map, int row, int col){
int n = map.length;
int[][] result = new int[n][n];
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
result[i][j] = map[i][j];
}
}
for(int i=0; i<n; i++){
result[i][col] = 1;
result[row][i] = 1;
}
int nextR = row;
int nextC = col;
while(nextR >= 0 && nextR < n && nextC >= 0 && nextC < n){
result[nextR++][nextC++] = 1;
}
nextR = row;
nextC = col;
while(nextR >= 0 && nextR < n && nextC >= 0 && nextC < n){
result[nextR++][nextC--] = 1;
}
return result;
}
}
결과를 문자열 리스트로 만드는 과정이 깔끔하지 않았다.
문자열을 다루는 것이 아직도 미숙하다. 좀 더 개선이 필요하다.
코드 개선
import java.util.*;
class Solution {
public List<List<String>> solveNQueens(int n) {
char[][] board = new char[n][n];
for(char[] arr : board){
Arrays.fill(arr, '.');
}
List<List<String>> result = new ArrayList<>();
dfs(0, board, result);
return result;
}
public void dfs(int row, char[][] board, List<List<String>> result){
if(row == board.length){
result.add(changeList(board));
return;
}
for(int col=0; col<board.length; col++){
if(isValid(row, col, board)){
board[row][col] = 'Q';
dfs(row+1, board, result);
board[row][col] = '.';
}
}
}
public boolean isValid(int row, int col, char[][] board){
for(int i=0; i<board.length; i++){
if(board[i][col] == 'Q') return false;
}
int nextR = row;
int nextC = col;
while(nextR>=0 && nextR<board.length && nextC>=0 && nextC<board.length){
if(board[nextR][nextC] == 'Q'){
return false;
}
nextR--;
nextC++;
}
nextR = row;
nextC = col;
while(nextR>=0 && nextR<board.length && nextC>=0 && nextC<board.length){
if(board[nextR][nextC] == 'Q'){
return false;
}
nextR--;
nextC--;
}
return true;
}
public List<String> changeList(char[][] board){
List<String> result = new ArrayList<>();
for(char[] arr : board){
result.add(new String(arr));
}
return result;
}
}반응형
'코딩 테스트 > 리트코드' 카테고리의 다른 글
| [리트코드] 207. Course Schedule (0) | 2024.02.01 |
|---|---|
| [리트코드] 743. Network Delay Time (0) | 2024.01.31 |
| [리트코드] 529. Minesweeper (0) | 2024.01.21 |