数据结构算法——剪枝

本文介绍了如何使用递归和剪枝策略解决经典的计算机科学问题——N皇后问题和数独问题。在N皇后问题中,通过设置存储皇后攻击范围的集合,利用递归实现解决方案,并清除已搜索过的皇后攻击范围。在数独问题上,通过检查行、列和小宫格内的元素避免重复,确保数独的有效性。同时,提供了解数独的思路。这些算法展示了在约束条件下寻找解决方案的有效方法。
摘要由CSDN通过智能技术生成

一、概述

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

二、例题

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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值