好像大部分人都是写的递归解,递归总有他的局限性,那就尝试下迭代解,和36题一样,用set简单处理一下空白位,但没有做剪枝和判断最少备选数的位置,然后进行迭代
思路为,每个空白位置存储三个数据,该点的坐标、该点的备选数(仅在处理该点时更新)和正在使用的备选数的序号,若存在备选数,则使用第一个,然后判断下一个点;若不存在备选数,退回上一个点,若存在更多备选方案,尝试下一个,若不存在,则继续回退,直到有解,使用指针来控制前进和回退
1 class Solution(object): 2 def solveSudoku(self, board): 3 list_row_comp = [] 4 list_col_comp = [] 5 list_block_comp = [] 6 universe = {"1", "2", "3", "4", "5", "6", "7", "8", "9"} 7 stack = [] 8 attempt_list = [] 9 for i in range(9): 10 set_row = set() 11 set_col = set() 12 for j in range(9): 13 this_row = board[i][j] 14 this_col = board[j][i] 15 if this_row == ".": 16 stack.append([i, j]) 17 else: 18 set_row.add(this_row) 19 if this_col != ".": 20 set_col.add(this_col) 21 list_row_comp.append(universe - set_row) 22 list_col_comp.append(universe - set_col) 23 24 arry = [[0, 1, 2], [3, 4, 5], [6, 7, 8]] 25 for i in range(3): 26 for j in range(3): 27 set_block = set() 28 for col in arry[i]: 29 for row in arry[j]: 30 this_block = board[col][row] 31 if this_block != ".": 32 set_block.add(this_block) 33 block_comp_list.append(universe - set_block) 34 35 pnt_stack, pnt_attempt = 0, 0 36 len_stack = len(stack) 37 attempt_list = [0 for i in range(len_stack)] 38 while pnt_stack < len_stack: 39 loc = stack[pnt_stack] 40 loc_block = 3 * int(loc[0] / 3) + int(loc[1] / 3) 41 available = list(row_comp_list[loc[0]] & col_comp_list[loc[1]] & block_comp_list[loc_block]) 42 # print(attempt_list) 43 if available: 44 num_this = available[0] 45 attempt_list[pnt_attempt] = [loc, available, 0] 46 row_comp_list[loc[0]].remove(num_this) 47 col_comp_list[loc[1]].remove(num_this) 48 block_comp_list[loc_block].remove(num_this) 49 pnt_stack += 1 50 pnt_attempt += 1 51 else: 52 while True: 53 pnt_attempt -= 1 54 last_try = attempt_list[pnt_attempt] 55 num_this = last_try[1][last_try[2]] 56 row_comp_list[last_try[0][0]].add(num_this) 57 col_comp_list[last_try[0][1]].add(num_this) 58 block_comp_list[3 * int(last_try[0][0] / 3) + int(last_try[0][1] / 3)].add(num_this) 59 60 if last_try[2] + 1 < len(last_try[1]): 61 last_try[2] += 1 62 attempt_list[pnt_attempt] = last_try 63 num_this = last_try[1][last_try[2]] 64 row_comp_list[last_try[0][0]].remove(num_this) 65 col_comp_list[last_try[0][1]].remove(num_this) 66 block_comp_list[3 * int(last_try[0][0] / 3) + int(last_try[0][1] / 3)].remove(num_this) 67 pnt_attempt += 1 68 break 69 else: 70 pnt_stack -= 1 71 72 for i in attempt_list: 73 board[i[0][0]][i[0][1]] = i[1][i[2]] 74 return board