递归函数未按预期返回:数独求解器solve函数返回None问题修复
问题分析
你的代码核心问题出在递归回溯的返回逻辑和全局变量的副作用上:
- 递归调用
solve()时,没有处理返回结果,即便下层递归找到了完整解并返回,上层递归依然会执行board[row][col] = 0的回溯操作,把刚填好的数字重置为0,最后走到函数末尾的空return(默认返回None)。 - 使用全局变量
board导致回溯过程中直接修改原数组,即便找到解,后续的回溯步骤会覆盖正确值。
修改方案
调整递归逻辑,让找到解时立即向上传递结果,同时避免全局变量的副作用:
board = [[5,3,0,0,7,0,0,0,0], [6,0,0,1,9,5,0,0,0], [0,9,8,0,0,0,0,6,0], [8,0,0,0,6,0,0,0,3], [4,0,0,8,0,3,0,0,1], [7,0,0,0,2,0,0,0,6], [0,6,0,0,0,0,2,8,0], [0,0,0,4,1,9,0,0,5], [0,0,0,0,8,0,0,7,9]] def solution(board, row, col, number): # 检查当前行是否存在该数字 for i in range(9): if board[row][i] == number: return False # 检查当前列是否存在该数字 for i in range(9): if board[i][col] == number: return False # 检查3x3小方格是否存在该数字 row0 = (row // 3) * 3 col0 = (col // 3) * 3 for i in range(3): for j in range(3): if board[row0+i][col0+j] == number: return False return True def solve(board): # 遍历每个格子 for row in range(9): for col in range(9): if board[row][col] == 0: # 尝试填入1-9 for number in range(1,10): if solution(board, row, col, number): board[row][col] = number # 递归求解,接收返回结果 result = solve(board) # 如果找到解,直接返回结果,终止回溯 if result is not None: return result # 没找到解,回溯 board[row][col] = 0 # 所有数字都尝试过,无解 return None # 所有格子填满,返回当前棋盘的深拷贝(避免后续修改影响结果) return [row.copy() for row in board] # 调用函数并验证结果 solved_board = solve(board) for row in solved_board: print(row) print("\n返回的求解结果:") print(solved_board)
修改要点说明
- 移除全局变量:将
board作为参数传递给solution和solve函数,避免全局变量的修改副作用。 - 递归结果传递:递归调用
solve(board)时接收返回值,一旦得到非None的结果(即找到完整解),立即向上返回该结果,不再执行后续的回溯操作。 - 返回深拷贝:当棋盘填满时,返回棋盘的深拷贝(
[row.copy() for row in board]),确保返回的结果不会被后续可能的回溯操作修改。 - 修复
solution函数逻辑:原代码中把3x3方格的检查放在了行检查的循环内,导致只检查第一行就返回,现在将这部分逻辑移到行和列检查的循环外,确保完整检查行、列和3x3方格。
内容的提问来源于stack exchange,提问作者Cristian Anton
相关产品推荐
相关产品推荐

