IT/Problem Solving

[LeetCode] Sudoku Solver (Java)

erinh 2024. 2. 23. 22:59
반응형

문제

문제풀이 1. 무지성 For문 

- 일단 스도쿠 판의 배열이 9*9로 정해져 있고,
하나의 solution만 있는 것이 보장되기 때문에, 무지성 반복문을 계속 돌려서 값을 넣어보는 방식을 채택했다.

class Solution {
    public void solveSudoku(char[][] board) {
        solve(board);
    }

    private boolean solve(char[][] board) {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board.length; j++) {
                if (board[i][j] == '.') {
                    for (char c = '1'; c <= '9'; c++) {
                        if (checkDup(board, i, j, c)) {
                            board[i][j] = c;
                            if (solve(board)) {
                                return true;
                            } else {
                                board[i][j] = '.';
                            }
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }

    private boolean checkDup(char[][] board, int row, int col, char c) {
        for (int i = 0; i < 9; i++) {
            if(board[i][col] == c || board[row][i] == c || 
            board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) {
                return false;
            }
        }
        return true;
    }
}

결과는 더헉..! 11초..? 미쳤다. 당장 단축해.
사실 위 방법을 사용하면, 이미 검색한 애들도 for문의 영향으로 또 돌기 때문에 굉장히 비효율적이다.

문제풀이2. 백트래킹을 통해서  재귀를 돌리자.

class Solution {
    
    public void solveSudoku(char[][] board) {
        solve(board, 0, 0);
    }

    private boolean solve(char[][] board, int row, int col) {
        // Entire board has been filled
        if (row == board.length) {
            return true;
        }

        // Move to next row
        if (col == board[0].length) {
            return solve(board, row + 1, 0);
        }

        // Skip cells
        if (board[row][col] != '.') {
            return solve(board, row, col + 1);
        }

        for (char c = '1'; c <= '9'; c++) {
            if (isValid(board, row, col, c)) {
                board[row][col] = c;
                if (solve(board, row, col + 1)) {
                    return true;
                }
                board[row][col] = '.';
            }
        }

        return false;
    }

    private boolean isValid(char[][] board, int row, int col, char c) {

        for (int i = 0; i < board.length; i++) {

            if (board[i][col] == c) {
                return false;
            }

            if (board[row][i] == c) {
                return false;
            }

            if (board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) {
                return false;
            }
        }

        return true;
    }
}

죠큼 단축 됐지만.. 만족스럽지 않아.. 다시 방법을 탐구해보아야겠다.

반응형