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); } }
修正说明
- 调整基准条件为
i == 9,确保所有行处理完成后终止递归。 - 列越界处理后添加
return,避免后续代码重复发起递归。 - 增加非0格子判断,跳过已填充的预设数字。
- 添加回溯操作:递归返回后将格子重置为0,恢复数独状态。
- 递归调用时判断返回值,找到有效解后直接返回,减少不必要的递归尝试。
内容的提问来源于stack exchange,提问作者user13664339
相关产品推荐
相关产品推荐

