数独求解程序递归问题:无法遍历空单元格
问题原因分析
你的代码有两个核心问题导致程序卡在第一个单元格:
return语句位置错误
你在第一个for cell循环的末尾直接写了return,这意味着程序处理完第一个单元格('00')的所有候选值后,就直接返回了,根本不会进入后续单元格的循环。递归调用后,函数执行完第一个cell的循环就终止,完全没有机会处理'01'、'06'这些单元格。全局empty_cells未动态更新
你使用的是全局的empty_cells字典,递归过程中没有判断当前单元格是否已经被填充。每次递归调用brute时,都会从头开始遍历empty_cells的第一个元素('00'),反复尝试填充它的候选值,导致无限递归在这个单元格上,直到触发递归深度限制。
修正方案
要解决这个问题,需要调整递归逻辑,让程序在填充完当前单元格后,继续处理剩余的空单元格,并且动态判断当前单元格是否为空:
def brute(board): # 先找到当前第一个空单元格 empty_cell = None for i in range(9): for j in range(9): if board[i][j] == ".": empty_cell = (i, j) break if empty_cell: break # 如果没有空单元格,说明数独已解,返回True if not empty_cell: return True row, col = empty_cell # 从全局empty_cells中获取当前单元格的候选值 for n in empty_cells[f"{row}{col}"]: board[row][col] = n # 递归尝试填充剩余单元格,如果成功就返回True if brute(board): return True # 回溯,恢复单元格为空 board[row][col] = "." # 当前单元格所有候选值都尝试过,无解,返回False return False
关键改进点
- 动态查找空单元格:每次递归时重新扫描棋盘,找到当前第一个空单元格,而不是依赖全局的固定列表,确保递归处理的是剩余未填充单元格。
- 正确的递归终止条件:当没有空单元格时,说明数独已解,返回True触发上层递归的成功终止。
- return时机调整:只有当递归成功解出剩余数独时才返回True,否则继续尝试当前单元格的下一个候选值;所有候选值尝试失败后,返回False进行回溯。
内容的提问来源于stack exchange,提问作者Sidd
相关产品推荐
相关产品推荐

