Java回溯数独算法改多解时遇无限运行、篡改非空单元格问题求解
数独回溯算法找所有解的错误修正
你的代码存在两个关键问题,导致无限运行且篡改非空单元格:
问题1:非空单元格处理后未终止当前分支
当遇到原始棋盘里的非空单元格(grid[row][column] != 0)时,递归调用下一个单元格后没有终止当前函数执行,导致后续的for循环继续运行,会把原本的非空值覆盖为0再尝试填入1-9,既篡改了原始数据,也会引发大量无效递归。
问题2:终止条件逻辑错误
原代码的终止条件只判断了最后一行处理完的情况,但当处理到第grid.length行(所有行都处理完毕)时,没有对应的终止逻辑,会继续执行后续代码,导致数组越界或无限递归。
修正后的代码
public static void solveSoduko(int[][] grid, int row, int column) { // 修正:终止条件改为row == grid.length,说明整个棋盘已处理完成 if(row == grid.length) { arrayPrint(grid); return; } if(column == grid.length) { row++; column = 0; // 递归进入下一行的第一个单元格,避免后续代码重复处理 solveSoduko(grid, row, column); return; // 这里要return,防止继续执行后面的代码 } if(grid[row][column] != 0) { solveSoduko(grid, row, column + 1); return; // 修正:处理完非空单元格后直接return,跳过后续for循环 } for(int i = 1; i <= 9; i++) { if(isValid(grid, row, column, i)){ grid[row][column] = i; solveSoduko(grid, row, column + 1); grid[row][column] = 0; // 回溯,恢复为0 } } }
关键修改说明
- 调整终止条件:当
row == grid.length时,说明所有行都已处理完毕,直接打印解并返回。 - 非空单元格处理后return:遇到原始非空值时,递归到下一个单元格后立即return,避免进入后续的for循环修改原始数据。
- 换行后直接递归并return:当column到边界时,换行后递归到下一行第一个单元格,然后return,防止后续代码重复执行。
内容的提问来源于stack exchange,提问作者Hadi Soueidan
相关产品推荐
相关产品推荐

