标签:可能性 row dfs 依次 target 清空 规律 完成后 info
判断一个9*9数组是否满足数独游戏规则:每行、每列、每3*3小格不能有相同的数。我的方法是按行进行遍历,同时用9个数组存储每列的数字,再用3个数组存储3个小格的数字(这3个数组每遍历完三行进行一次清空);遍历的同时判断新发现的数字在对应的行、列、3*3小格里是否已经存在,存在的话直接返回False。遍历完成后返回True。代码:
class Solution(object): def isValidSudoku(self, board): """ :type board: List[List[str]] :rtype: bool """ columns = [[] for _i in xrange(9)] boxes = [[] for _i in xrange(3)] for i in xrange(9): _tempRow = [] if i % 3 == 0: boxes = [[] for _i in xrange(3)] for j in xrange(9): _c = board[i][j] currBox = boxes[j / 3] if _c != ‘.‘: if _c in currBox or _c in columns[j] or _c in _tempRow: return False else: currBox.append(_c) _tempRow.append(_c) columns[j].append(_c) return True
数独填空,上一题的进一步扩展。给出一个9*9数组,里面有空格和数字,用1-9填满空格,并使数组满足数独规则。思路是首先找出所有的空格位置并用一个数组存储下来,并且把9*9数组拆分为9行、9列、9小格来分别进行合法性判定。然后利用递归依次对空格位置尝试进行填补,用来填补的数由当前的行、列、小格的情况获得,填补成功,则把所有的状态传入下一个递归循环,所有可能性失败则退回上一层递归。代码:
class Solution: def getPosNums(self, board, position, rows, columns, sub_boxes): nums = [] row, column = position box_idx = (row // 3) * 3 + column // 3 for s in map(str, range(1, 10)): if (not s in rows[row]) and (not s in columns[column]) and (not s in sub_boxes[box_idx]): nums.append(s) return nums def init(self, board, emptyPos, rows, columns, sub_boxes): for i in range(9): for j in range(9): tmp = board[i][j] if tmp != ‘.‘: rows[i].add(tmp) columns[j].add(tmp) box_idx = (i // 3) * 3 + (j // 3) sub_boxes[box_idx].add(tmp) else: emptyPos.append((i, j)) return def solveSudoku(self, board): emptyPos = [] rows = [set() for i in range(9)] columns = [set() for i in range(9)] sub_boxes = [set() for i in range(9)] self.init(board, emptyPos, rows, columns, sub_boxes) def solve(board, positions): if not positions: return True posNums = self.getPosNums(board, positions[0], rows, columns, sub_boxes) if not posNums: return False row, column = positions[0] box_idx = (row // 3) * 3 + (column // 3) for s in posNums: board[row][column] = s rows[row].add(s) columns[column].add(s) sub_boxes[box_idx].add(s) if solve(board, positions[1:]): return True rows[row].remove(s) columns[column].remove(s) sub_boxes[box_idx].remove(s) board[row][column] = ‘.‘ return False solve(board, emptyPos) return
按照题目中给出的这个规律(后一项是对前一项的描述,比如第三项是21,那么对其描述为:一个2和一个1,即1211),结合题目给出的整数n,返回这个规律下第n下的字符串。给出的n不会超过30,所以按照规则一项一项地求出第n项即可,用一个front记录上一项的结果,代码:
class Solution(object): def countAndSay(self, n): """ :type n: int :rtype: str """ if n == 1: return ‘1‘ front = None output = ‘‘ for idx, i in enumerate(self.countAndSay(n-1)): if i != front: if front != None: output = output + str(count) + front elif idx == 0 and n == 2: output = output + str(1) + i front = i count = 1 else: count += 1 if n > 2: output = output + str(count) + i return output
给出一个数组合一个目标数target,找出这个数组中相加和为target的所有组合。思路是利用递归的方法,先对数组进行排序,然后递归查找组合可能性,当前和满足要求则记录。代码:
class Solution(object): def combinationSum(self, candidates, target): res = [] candidates.sort() self.dfs(candidates, target, 0, [], res) return res def dfs(self, nums, target, index, path, res): if target < 0: return if target == 0: res.append(path) return for i in xrange(index, len(nums)): self.dfs(nums, target-nums[i], i, path+[nums[i]], res)
上一题的扩展,新增的要求是原有数组中的数不能在一个可能性组合里重复使用。思路和上一题一样,只需要注意进行递归时,传入下一层递归循环的剩余可使用的数需要剔除当前这一层使用到的数。代码:
class Solution(object): def combinationSum2(self, candidates, target): """ :type candidates: List[int] :type target: int :rtype: List[List[int]] """ if not candidates: return [] ret = [] def fn(nums, tmp): if sum(tmp) > target: return False elif sum(tmp) == target: if tmp not in ret: ret.append(tmp) return True else: for i in range(len(nums)): if i>0 and nums[i] == nums[i-1]: continue fn(nums[i+1:],tmp+[nums[i]]) candidates.sort() fn(candidates,[]) return ret
标签:可能性 row dfs 依次 target 清空 规律 完成后 info
原文地址:https://www.cnblogs.com/HorribleMe/p/12819884.html