python不用递归方法解数独
时间: 2023-05-31 07:03:32 浏览: 88
数独问题可以使用回溯算法来解决,不一定需要递归。下面是一个不使用递归的数独求解算法:
1. 初始化一个空的9x9的数独矩阵,并将待填充的位置标记为0。
2. 创建一个栈stack,用于存储待填充的位置。
3. 找到数独矩阵中的一个空格(值为0),将其位置压入栈stack中。
4. 对于栈中的每个待填充位置,从1到9尝试填充数字,判断该位置是否符合数独规则,如果符合,则将该位置的值更新为填充的数字,并将该位置的所有相关位置(同行、同列、同宫)的候选数字集合更新。
5. 如果填充的数字与已有的数字冲突,或者无法填充数字,则回溯到上一个待填充位置,将该位置的值重新标记为0,并将其从栈stack中弹出。
6. 如果栈stack为空,则表示数独已经被成功填充,算法结束。
下面是一个Python代码实现:
```python
def solve_sudoku(board):
stack = []
for i in range(9):
for j in range(9):
if board[i][j] == 0:
stack.append((i, j))
while stack:
i, j = stack[-1]
found = False
for num in range(board[i][j] + 1, 10):
if is_valid(board, i, j, num):
board[i][j] = num
update_candidates(board, i, j, num)
stack.pop()
found = True
break
if not found:
board[i][j] = 0
update_candidates(board, i, j, 0)
stack.pop()
if not stack:
return False
i, j = stack[-1]
return True
def is_valid(board, i, j, num):
for k in range(9):
if board[i][k] == num or board[k][j] == num or board[(i//3)*3+k//3][(j//3)*3+k%3] == num:
return False
return True
def update_candidates(board, i, j, num):
for k in range(9):
if board[i][k] == 0:
board[i][k] = {1,2,3,4,5,6,7,8,9} - set(board[i]) - get_col(board, k) - get_box(board, i//3, k//3)
if len(board[i][k]) == 1:
board[i][k] = board[i][k].pop()
if board[k][j] == 0:
board[k][j] = {1,2,3,4,5,6,7,8,9} - set(board[k]) - get_col(board, j) - get_box(board, k//3, j//3)
if len(board[k][j]) == 1:
board[k][j] = board[k][j].pop()
def get_col(board, j):
return [board[i][j] for i in range(9)]
def get_box(board, i, j):
return [board[m][n] for m in range(i*3, (i+1)*3) for n in range(j*3, (j+1)*3)]
```
其中,is_valid函数用于判断填充的数字是否符合数独规则;update_candidates函数用于更新每个位置的候选数字集合。如果候选数字集合只有一个元素,则直接填充该数字。
该算法的时间复杂度为指数级别,但是在实际应用中,由于数独中待填充的位置较少,因此算法的实际运行时间较短。