Алгоритм решения судоку с бэк-трекингом

Я пытаюсь реализовать очень простой алгоритм, который использует обратное отслеживание методом грубой силы для решения сеток Судоку. Проблема, с которой я сталкиваюсь, заключается в том, что в моей реализации я включил две переменные экземпляра дляSudoku класс называетсяrow а такжеcol, которые соответствуют строке и столбцу пустой ячейки в двумерном массиве, который представляет сетку судоку.

Когда мойsolve() Метод выполняет сначала проверку, чтобы увидеть, нет ли пустых ячеек, и в этом случае головоломка уже завершена. В противном случае этот же метод назначает строку и столбец пустой ячейки переменным экземпляра.row а такжеcol изSudoku объект, который содержит сетку. После этого цикл for проверяет, какое число может быть помещено в эту пустую ячейку с помощью вызова метода.isSafe(int n) (Этот метод проверяет, соблюдаются ли ограничения головоломки, я могу гарантировать, что она отлично работает). Так чтоisSafe() метод помещает число в пустую ячейку, а затем делает рекурсивный вызовsolve() метод снова наSudoku объект.

Если мы столкнемся с ограничением, которое не может быть выполнено, то мы переназначим0 до концаrow а такжеcol это было заполнено. Это где проблема найдена! Так как программа постоянно обновляетrow а такжеcol переменных, то старые экземпляры теряются при каждом рекурсивном вызове. Я пытался выяснить, как сохранить эти значения, чтобы программа могла отменить действия, когда она возвращается. Я думал о толкании каждогоcol а такжеrow в стек, но я действительно не уверен, куда идти.

Может кто-нибудь сказать мне, что было бы простым способом решить эту проблему? Я не включаю весь класс, если вы думаете, что это будет полезно, дайте мне знать, и я опубликую это.

class Sudoku {
    int SIZE, N, row, col;
    int Grid[][];    

    public boolean solve() {
        if (!this.findNextZero()) return true;

        for (int num = 1; num <= 9; num++) {
            if (isSafe(num)) {
                this.Grid[this.row][this.col] = num;

                if (this.solve()) return true;

                this.Grid[this.row][this.col] = 0;
                // this.Grid[oldRow][oldCol] = 0;
            }
        }
        return false;
    }

    public boolean findNextZero() {
        for (int i = 0; i < this.N; i++) {
            for (int j = 0; j < this.N; j++) {
                if (this.Grid[i][j] == 0) {
                    this.row = i;
                    this.col = j;
                    return true;
                }
            }
        }
        return false;
    }

    public boolean isSafe(int num) {
        return !this.usedInRow(num) 
                && !this.usedInColumn(num) 
                && !this.usedInBox(num);
    }

Если бы я должен был реализовать стек, имеет ли смысл следующее? ПослеfindNextZero() операции подтолкнутьrow а такжеcol целые числа в стек. Продолжайте делать это, а затем измените следующую строку кода

this.Grid[this.row][this.col] = 0;

что-то вроде

this.Grid[s.pop][s.pop] = 0;

Это разумный подход?

Ответы на вопрос(3)

Ваш ответ на вопрос