数据结构算法——剪枝
一、概述
例题只能暴力搜索,配上剪枝降低计算量
二、例题
2.1 N皇后问题(Leetcode 51)
解题思路:用set来保存已有皇后攻击范围的坐标运算常数;用递归完美解决用过的皇后的攻击范围清除
class Solution(object): def solveNQueens(self, n): """ :type n: int :rtype: List[List[str]] """ self.result = [] # 存储所有n皇后路径的结果 self.col, self.pie, self.na = set(), set(), set() # 分别存储皇后攻击的路径 self.DFS(n, 0, []) # 开始递归 return self.generate_result(self.result) # 转换格式 def DFS(self, n, row, cur_state): """ n代表总共有几行 row代表当前在第几行 cur_state代表当前的n皇后路径 """ if row>=n: self.result.append(cur_state) return for col in range(n): if col not in self.col and row-col not in self.pie and row+col not in self.na: # 将该层的此皇后攻击的范围加入存储 self.col.add(col) self.pie.add(row-col) self.na.add(row+col) # 基于该层的此皇后的攻击范围,去找下一层能放棋子的位置 self.DFS(n, row+1, cur_state+[col]) # 基于该层的此皇后的攻击范围,已经完成了后续所有层的搜素,所以现在把该层的此皇后的攻击范围删除,目的是要遍历到该层的下一个皇后位置 self.col.remove(col) self.pie.remove(row-col) self.na.remove(row+col) return def generate_result(self, result): # 根据n皇后路径的结果集合,转换到题目要求的格式 final_result = [] for i in range(len(result)): sub_result = [] for j in range(len(result[i])): tmp = [. for _ in range(len(result[i]))] tmp[result[i][j]] = "Q" sub_result.append(.join(tmp)) final_result.append(sub_result) return final_result
2.2 数独问题(Leetcode 36、37)
2.2.1 有效数独(Leetcode 36)
判断这道数独题目有没有出错(出错就是“行”、“列”、“三宫格”内出现了重复元素)。
class Solution(object): def isValidSudoku(self, board): """ :type board: List[List[str]] :rtype: bool """ # 定义存储“行”、“列”、“三宫格”的单元,用于判断是否有重复元素 self.col = [set() for _ in range(9)] self.row = [set() for _ in range(9)] self.square = [[set() for _ in range(3)] for _ in range(3)] # 开始遍历数独的每一个有效元素 for i in range(9): for j in range(9): cur = board[i][j] if cur == .: continue if cur not in self.row[i]: self.row[i].add(cur) else: return False if cur not in self.col[j]: self.col[j].add(cur) else: return False if cur not in self.square[i/3][j/3]: self.square[i/3][j/3].add(cur) else: return False return True