You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java数独求解器代码栈溢出问题排查求助

数独求解器栈溢出问题排查与修复

核心问题分析

你的代码出现栈溢出(Stack Overflow Error)且无法得到正确解,是以下几个逻辑错误导致:


1. 基准条件不完整且错误

当前仅判断i == 8 && j == 8作为终止条件,但数独是9行(索引0-8),处理完第8行第8列后后续递归仍会持续执行。正确的终止条件应为**i == 9**,此时所有行已处理完成,说明找到有效解。

2. 递归分支未终止,引发无限递归

当j == sudoku[i].length(即j=9,超出当前行的列数),调用sudokuSolver(sudoku, i+1, 0)后未加return终止当前方法的后续逻辑,导致后面的for循环仍会执行,重复发起递归请求,栈深度急剧增加。

3. 缺少回溯操作

尝试填充数字n并递归调用sudokuSolver(sudoku, i, j+1)后,递归返回时未将当前格子重置为0(撤销选择),导致后续尝试其他数字时,格子值被错误保留,破坏数独状态,同时产生大量无效递归路径。

4. 未跳过已填充的格子

原代码未判断当前格子是否为0(未填充),如果是预设的非0数字,直接尝试填充会覆盖原有值并产生无效判断,应直接跳过此类格子。


修正后的完整代码

public class Sudoku {
    public static void printSudoku(int sudoku[][]) {
        for (int i = 0; i < sudoku.length; i++) {
            for (int j = 0; j < sudoku[i].length; j++) {
                System.out.print(sudoku[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println("---------------------");
    }

    public static boolean sudokuSolver(int sudoku[][], int i, int j) {
        // 基准条件:所有行处理完成,找到有效解
        if (i == 9) {
            printSudoku(sudoku);
            return true; // 返回true表示找到解,提前终止递归
        }

        // 处理列越界:切换到下一行第一列
        if (j == 9) {
            return sudokuSolver(sudoku, i + 1, 0);
        }

        // 如果当前格子已有数字,直接跳过,处理下一列
        if (sudoku[i][j] != 0) {
            return sudokuSolver(sudoku, i, j + 1);
        }

        // 尝试填充1-9的数字
        for (int n = 1; n <= 9; n++) {
            if (isSafe(sudoku, i, j, n)) {
                sudoku[i][j] = n;
                // 递归处理下一列,找到解直接返回,不再尝试其他数字
                if (sudokuSolver(sudoku, i, j + 1)) {
                    return true;
                }
                // 回溯:撤销当前选择,尝试下一个数字
                sudoku[i][j] = 0;
            }
        }
        // 当前格子无有效数字可填,回溯到上一层
        return false;
    }

    public static boolean isSafe(int sudoku[][], int i, int j, int n) {
        // 检查当前行
        for (int c = 0; c < 9; c++) {
            if (sudoku[i][c] == n) {
                return false;
            }
        }
        // 检查当前列
        for (int r = 0; r < 9; r++) {
            if (sudoku[r][j] == n) {
                return false;
            }
        }

        // 检查3x3小矩阵
        int sr = (i / 3) * 3;
        int sc = (j / 3) * 3;
        for (int r = sr; r < sr + 3; r++) {
            for (int c = sc; c < sc + 3; c++) {
                if (sudoku[r][c] == n) {
                    return false;
                }
            }
        }
        return true;
    }

    public static void main(String[] args) {
        int sudoku[][] = {
                {0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0},
                {0,0,0,0,0,0,0,0,0}
        };
        sudokuSolver(sudoku, 0, 0);
    }
}

修正说明

  1. 调整基准条件为i == 9,确保所有行处理完成后终止递归。
  2. 列越界处理后添加return,避免后续代码重复发起递归。
  3. 增加非0格子判断,跳过已填充的预设数字。
  4. 添加回溯操作:递归返回后将格子重置为0,恢复数独状态。
  5. 递归调用时判断返回值,找到有效解后直接返回,减少不必要的递归尝试。

内容的提问来源于stack exchange,提问作者user13664339

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:00:10