力扣leetcode37. 解数独

好像大部分人都是写的递归解,递归总有他的局限性,那就尝试下迭代解,和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

 

posted @ 2020-03-23 15:35  Pyrokine  阅读(199)  评论(0编辑  收藏  举报