数据结构算法——剪枝

目录

  • 一、概述
  • 二、例题
    • 2.1 N皇后问题(Leetcode 51)
    • 2.2 数独问题(Leetcode 36、37)
      • 2.2.1 有效数独(Leetcode 36)
      • 2.2.2 解数独(Leetcode 37)

一、概述

例题只能暴力搜索,配上剪枝降低计算量

二、例题

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

2.2.2 解数独(Leetcode 37)

你可能感兴趣的:(数据结构算法,数据结构)