DFS와 백트래킹

DFS

  • 깊이 우선 탐색으로 가능한 모든 경로를 탐색한다.
  • 모든 경우의 수를 탐색하기 때문에 경우의 수를 줄이지는 못한다.

백트래킹

  • 재귀적으로 문제를 해결 하지만 확인 중인 상태가 제한 조건에 맞는 지 확인하고 해당 상태가 조건에 맞지 않으면 제외한다.
  • 위와 같이 조건에 맞지 않는 것을 제외 하는 것을 가지치기라고 한다.

N-Queen

백트래킹의 예시로 N-Queen 문제가 있다. 처음에 DFS으로 접근을 하였었으나 시간 초과가 발생하였다. 따라서 이를 해결하기 위해 조건에 맞지 않는 것을 제외 하는 방법으로 접근 하였다.

접근 방법

  • 일차원 배열의 row 값은 퀸이 놓여져 있는 열의 값을 의미한다.
  • 직선의 경우 배열의 값을 비교하면 되고 대각선은 기울기를 비교하면 된다.

dfs 재귀 Method

depth 즉 현재 주어진 배열의 길이만큼 재귀가 돌아가며 dp 배열에는 Queen이 놓아지는 위치가 출력이 된다.

public void dfs(int depth, int n) {  
    // 들어간 깊이가 주어진 n과 같아지만 멈춘다.  
    if (depth == n) {  
        answer += 1;  
        System.out.println(Arrays.toString(this.dp));  
        return;  
    }  
  
    for (int i = 0; i < n; i++) {  
        this.dp[depth] = i;  
        if (checkValid(depth)) {  
            dfs(depth + 1, n);  
        }  
    }  
}

loc 행 dp[loc]

dp 출력 예시

n이 4일 때

[1, 3, 0, 2]
[2, 0, 3, 1]

Queen을 둘 수 있는 지 검증

public boolean checkValid(int loc) {  
    boolean isContinue = true;  
    for (int i = 0; i < loc; i++) {  
		// 같은 세로 라인에 있는지 점검한다.
		// i < loc => 현재 라인 이전 까지 확인을 하는 것이다.
        if (this.dp[loc] == this.dp[i]) {  
            isContinue = false;  
        }  
        // 같은 기울기에 있는 지 점검한다. 
        // 대각선의 경우 행의 차이와 열의 차이가 같기 때문이다.
        if (Math.abs(loc - i) == Math.abs(this.dp[loc] - this.dp[i])) {  
            isContinue = false;  
        }  
    }  
    return isContinue;  
}