1. ๋ฌธ์ ์ค๋ช
2. ์ ๊ทผ ๋ฐฉ์
KEY WORD
: BACK-TRACKING
(0) ์ฌ์ ์ธํ
1์ฐจ์ ๋ฐฐ์ด(arr)์ n์ ํฌ๊ธฐ๋งํผ ๋ง๋ค๊ณ ๋ฐฐ์ด์ index
= ํ , ๋ฐฐ์ด์ value
= ์ด๋ก ์๊ฐํ๋ค.
์๋ฅผ ๋ค์ด ๋ฐฐ์ด์ด ๋ค์๊ณผ ๊ฐ์ ๋, ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ด๋ฉด ์ด๋ ๊ฒ ๋๋ค.
index(ํ) | 0 | 1 | 2 | 3 |
---|---|---|---|---|
value(์ด) | 1 | 3 | 0 | 2 |
(1) ๋ง์ฝ์ arr[i] = j ๋ผ๊ณ ํ๋ค๋ฉด 2์ฐจ์ ๋ฐฐ์ด [i] [j] ์ ํธ์ ๋๊ฒ ๋ค๋ ์๋ฆฌ์ด๋ค. ์ด๊ฒ ๊ฐ๋ฅํ์ง ์ฒดํฌํ๋ค. ์ฒดํฌํ๋ ๋ฐฉ๋ฒ์
0 ~ i-1 ๊น์ง์ ๋ฐฐ์ด ๊ฐ์ ์ด์ฉํด, ์ด์ ์ ๋๋ ํธ์ ๊ณต๊ฒฉ ๊ฒฝ๋ก์ ๊ฒน์น๋์ง ํ์ธํ๋ฉด ๋๋ค. ํ์ธ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
(1-1) ์ขํ๋จ ํ์ธ
๋๊ฐ์ ์ด ์ผ์นํ๋ ๊ฐ๋ค์ ๋ชจ๋ ํ+์ด์ ํฉ์ด ๊ฐ๋ค. ์ด๋ฅผ ์ด์ฉํ๋ค. ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ๋ index๊ฐ ํ์ด๊ณ value๊ฐ ์ด์ด๋๊นindex + arr[index]
๊ฐ ๊ฐ์์ง ํ์ธํ๋ฉด ๋๋ค.
(2) ์ฐํ๋จ ํ์ธ
์ฐํ๋จ์ ๊ฒฝ์ฐ, ํ๋ผ๋ฆฌ์ ์ฐจ์ ์ด๋ผ๋ฆฌ์ ์ฐจ๊ฐ ๊ฐ์ผ๋ฉด ๊ฐ์ ๋๊ฐ์ ์์ ๋์ฌ์๋ ๊ฒ์ด๋ค.
(3) ๊ฐ์ ์ด์ ์๋์ง ํ์ธ
๋ฐฐ์ด์ value ๊ฐ ์ด์ด์์์ผ๋ก, ๊ฐ์ ๊ฐ์ ๊ฐ์ง ๋ฐฐ์ด์ ์์๊ฐ ์๋์ง ํ์ธํ๋ฉด ๋๋ค.
3. ์ฝ๋ ๋ถ์
import java.io.*;
import java.util.*;
class Solution {
// index = ํ, value = ์ด
static int [] board;
static int cnt = 0;
public int solution(int n) {
board = new int [n];
backTracking(0);
return cnt;
}
public void backTracking(int depth) {
if(depth == board.length){
cnt++;
return;
}
for(int i = 0; i < board.length; i++){
board[depth] = i;
if(possibility(depth)){backTracking(depth+1);}
}
}
// ํ์ฌ ํ์ ํธ์ด ๋ค์ด๊ฐ ๊ฐ์ด ๋๋์ง ์๋๋์ง ์ฒดํฌ (์ด์ ๊ฐ๋ค์ ์ด์ฉ ์ขํ๋จ, ์ฐํ๋จ, ์ธ๋ก)
public boolean possibility(int index) {
for(int i = 0; i < index; i ++) {
// ์ขํ๋จ
if(board[index] + index == board[i] + i) return false;
// ์ฐํ๋จ
int diff = index - i;
if(board[i] + diff == board[index]) return false;
// ์ธ๋ก
if(board[i] == board[index]) return false;
}
return true;
}
}
4. ์ฑ์ฅ ํ๊ธฐ
A. ์ฒ์์ ๊ณ ๋ คํ๋ ์๋ชป๋ ์ ๊ทผ ๋ฐฉ์ - 2์ฐจ์ ๋ฐฐ์ด์์ ๋ถ๊ฐ๋ฅํ ์นธ ์ผ์ผํ ์ง์ฐ๊ธฐ
(1) ์ฒด์คํ์ 2์ฐจ์ ๋ฐฐ์ด๋ก ์๊ฐํ๊ณ , 0ํ ๋ถํฐ n-1ํ๊น์ง ์ฐจ๋ก๋๋ก ํ์ํ๋ค. (์ฌ๊ท ์ด์ฉํ์ฌ ๋ค์ ํ ํ์)
(2) ๊ฐ ํ์ ํธ์ ๋์์ ๋, ๊ทธ ํธ์ ๊ณต๊ฒฉ ๊ฒฝ๋ก๋ฅผ ๋ชจ๋ X
ํ์ ํด๋๋ ์์ผ๋ก ๋ถ๊ฐ๋ฅํ ์นธ์ ์ง์๋๊ฐ๋ค.
(3-1) ๋ง์ฝ ํ์ ํ์ํ๋๋ฐ ๋ชจ๋ ์นธ์ด X
ํ์ ์ด๋ฉด ํด๋น ๊ฒฝ์ฐ์ ์์์๋ N-queen ์ฑ๋ฆฝ์ด ๋ถ๊ฐ๋ฅ ํ๋ฏ๋ก, ์ด์ ์ฌ๊ท๋ก ๋์๊ฐ๋ค.
(3-2) ๋ง์ง๋ง ํ๊น์ง ํธ์ ๋๋๋ฐ ์ฑ๊ณตํ๋ค๋ฉด, ๊ฐ๋ฅํ ๊ฒฝ์ฐ์ ์๋ฅผ ํ๋ ์ฌ๋ฆฐ๋ค.
ํ์ง๋ง ํด๋น ๋ฐฉ๋ฒ์ ์ ๋๋ก ๊ตฌํํ๋๋ฐ ์๊ฐํด์ผํ ๋ถ๋ถ์ด ๋ง๊ณ , ๋ถ๊ฐ๋ฅํ ์นธ์ ์ง์ฐ๋ ๊ณผ์ ์์ ๋ฐ๋ณต๋ฌธ์ด ๋ง์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ๋นํจ์จ์ ์ด๋ค.
(1)์ ๋๋ก ๊ตฌํํ๋๋ฐ ๊ฑธ๋ฆผ๋ : ์ฌ๊ท์์ ๋๋์ ์ฌ ๋, ๋ถ๊ฐ๋ฅํ ์นธ์ ๋ค์ ๊ฐ๋ฅํ ์นธ์ผ๋ก ๋ฐ๊พธ๋ ๊ฒฝ์ฐ
๋ค์๊ณผ ๊ฐ์ด Queen์ด ์๋ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด๋ณด์. ์ด๋, ๊ณต๊ฒฉ ๊ฒฝ๋ก๊ฐ ๊ฒน์น๋ค.
1,3์ ์๋ queen์ ์ ๊ฑฐํ๋ค๊ณ ํ์ ๋, ์ด queen์ ๊ณต๊ฒฉ ๊ฒฝ๋ก๋ ๋ชจ๋ ๋ค์ ๊ฐ๋ฅํ ๊ฒฝ๋ก๋ก check ์ํฌ ๊ฒ์ด๋ค. ์ด๋ (2,2)๋ queen์ ๋ ์ ์๋ ๊ฐ๋ฅํ ๊ฒฝ๋ก๋ก ๋์๊ฐ๋ฒ๋ฆฌ๊ฒ ๋๋ค. ์ด๋ฌํ ํฌ์ธํธ์์ ๊ณ์ฐ์ด ์๋ชป๋๊ฒ ๋๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด์, ๋ถ๊ฐ๋ฅํ ๊ฒฝ๋ก์ stack point (๊ฒน์น ๋๋ง๋ค +1, ๊ฒฝ๋ก ์ ๊ฑฐ ์์๋ - 1, 0์ด ๋๋ฉด ๊ฐ๋ฅํ ๊ฒฝ๋ก)๋ก ํ์ํ ์๋ ์์ง๋ง, ์ฝ๋๋๊ณผ ์๊ฐํด์ผํ ๊ฒ ๋ง์์ ธ์ ๋นํจ์จ์ ์ด๋ค.
(2) ๋ถ๊ฐ๋ฅํ ๊ฒฝ๋ก ์ฒดํฌ, ๋ค์ ๊ฐ๋ฅํ ๊ฒฝ๋ก๋ก ๋ง๋๋๋ฐ, ๋ฐ๋ณต๋ฌธ์ด ์์ฒญ ๋ค์ด๊ฐ.
์๋๋ A ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌ์ฑํ ๋ด ์ฝ๋์ด๋ค.
๋๋ ์ค๋ณต๋๋ ๋ถ๊ฐ๋ฅํ ๊ฒฝ๋ก์ ๋ํด์ ์๊ฐํ์ง ์์์, ๋ถ๊ฐ๋ฅํ ๊ฒฝ๋ก ์ฒดํฌ๊ฐ ์ ๋๋ก ๋์ง ์์, ๋ฐฑํธ๋ํน์ ๊ฐ์ง์น๊ธฐ๊ฐ ์ ๋๋ก ๋์ง ์์๋ค. ๊ทธ ๊ฒฐ๊ณผ ์๊ฐ ์ด๊ณผ๋ ๋๊ณ , ๋ต๋ ํ๋ ธ๋ค.
import java.io.*;
import java.util.*;
class Solution {
static int [][] board;
static int cnt = 0;
public int solution(int n) {
board = new int[n][n];
backTracking(0);
return cnt;
}
public void backTracking(int depth) {
// for(int [] temp : board){
// System.out.println(Arrays.toString(temp));
// }
// System.out.println("-----------------------");
// 1. ๊ธฐ์ ์กฐ๊ฑด
if(depth == board.length) {
cnt++;
return;
}
// 2. ๊ณ์ฐ ์กฐ๊ฑด
for(int i = 0; i < board.length; i++){
if(board[depth][i] == 0){
board[depth][i] = 1;
left( depth, i, 1);
right( depth, i, 1);
sero( depth, i, 1);
backTracking(depth+1);
board[depth][i] = 0;
left( depth, i, 0);
right( depth, i, 0);
sero( depth, i, 0);
}
}
}
// ์ข ๋๊ฐ
public void left(int x, int y, int value) {
while(x >=0 && x < board.length && y >= 0 && y < board.length ) {
board[x][y] = value;
x++; y--;
}
}
// ์ฐ ๋๊ฐ
public void right(int x, int y, int value) {
while(x >=0 && x < board.length && y >= 0 && y < board.length) {
board[x][y] = value;
x++; y++;
}
}
// ์ธ๋ก
public void sero(int x, int y, int value) {
for(int i = x; i < board.length; i++) {
board[i][y] = value;
}
}
}