数据结构算法刷题(28)回溯组合型和全排列

news2024/12/23 5:14:07

剪枝技巧:

 

 思路:剪枝的特点是找特定长度的子集。首先确定大框架,当path的长度等于k的时候,就要更新答案并且return。然后在进行path的元素选择,这里采用倒叙,从i到d(d=k-len(path))倒着加入path中。

class Solution:

    def combine(self, n: int, k: int) -> List[List[int]]:

        path = []

        ans = []

        def dfs(i):

            d = k - len(path)

            # if i < d:

            #     return

            if len(path) == k:

                ans.append(path.copy())

                return

            for j in range(i,d-1,-1):

                path.append(j)

                dfs(j-1)

                path.pop()

        dfs(n)

        return ans

 思路:首先在[1,9]中选出不同的k个元素的子集,如果sum(path)==n,就更新答案。其余都是剪枝的套路代码。

class Solution:

    def combinationSum3(self, k: int, n: int) -> List[List[int]]:

        nums = [i for i in range(1,10)]

        ans = []

        path = []

        def dfs(i):

            d = k - len(path)

            if len(path) == k:

                if sum(path) == n:

                    ans.append(path.copy())

                return

            for j in range(i,d-1,-1):

                path.append(j)

                dfs(j-1)

                path.pop()

        dfs(len(nums)) #传入子集的总的区间长度

        return ans

思路:相当于从2n个位置上,选择n个位置放置左括号,但是左右括号是有约束的,左括号不能超过n,右括号不能超过左括号。当把这2n个位置填完,就更新答案。因为左括号的个数也是约束条件,所以和函数一起递归。

 

class Solution:

    def generateParenthesis(self, n: int) -> List[str]:

        #可以看成2n个位置上,选择(填入还是选择)填入

        ans = []

        m = n*2

        path = ['']*m

        def dfs(i,numofleft):

            if i == m:

                ans.append(''.join(path))

                return

            if numofleft < n:#左括号最大是n

                path[i] = '('

                dfs(i+1,numofleft+1)

            if i - numofleft < numofleft: #右括号的个数不能超过左括号

                path[i] = ')'

                dfs(i+1,numofleft)

        dfs(0,0)

        return ans

思路:在每一个位置上,选择一个数填入,但是该数和前面的数不能相同,维护一个s,来存放当前可以选的数字,每次加入path之后,就把该数字减去。

class Solution:

    def permute(self, nums: List[int]) -> List[List[int]]:

        ans = []

        path = []

        n = len(nums)

        def dfs(i,s):

            if i == n:

                ans.append(path.copy())

                return

            for x in s:

                path.append(x)

                dfs(i+1,s-{x})

                path.pop()

        dfs(0,set(nums))

        return ans

 或者维护一个是否在路径中的list,当list中相应的位置是Fasle,就输入path,然后恢复现场。

class Solution:

    def permute(self, nums: List[int]) -> List[List[int]]:

        ans = []

        path = []

        n = len(nums)

        on_path = [False]*n

        def dfs(i):

            if i == n:

                ans.append(path.copy())

                return

            for j in range(n):

                if not on_path[j]:

                    path.append(nums[j])

                    on_path[j] = True

                    dfs(i+1)

                    on_path[j] = False #恢复现场

                    path.pop() #恢复现场

        dfs(0)

        return ans

 

 

 思路:皇后要在每一行都放置一个,那我们来递归行数,正确答案就应该是确定的一个列的顺序。之前的path就相当于cols,用全排列的方式,将行数和可以选择的列传入递归中。有两个点:

第一如何构造答案:在cols之前,有cols个. 在其之后有(n-1-cols)个.中间再拼接上Q。

第二是如何避免对角线打架:因为我们是按照从上到下的行数来放置的,所以只需要考虑左上方和右上方的数据,左上方和皇后位置的行列和一致,右上方和皇后位置的行列差一致。计算当前行列和、行列差,与cols中已经有的行列和、行列差对比。

class Solution:

    def solveNQueens(self, n: int) -> List[List[str]]:

        #每一行都要放置一个皇后,那就在于,这个列的排序

        ans = []

        cols = [0]*n

        def dfs(i,s):#把行数和当前可以选择的列传进去

            if i == n:

                ans.append(['.'*c + 'Q'+'.'*(n-1-c) for c in cols]) #对于每一个结果,拼接ans

                return

            for j in s: #枚举列

                if all( j+i != cols[I] + I  and j-i != cols[I] - I for I in range(i)):#这里要保证不在一个对角线上,cols[I]就是有皇后的位置的列。

                    cols[i] = j

                    dfs(i+1,s-{j})

        dfs(0,set(range(n)))

        return ans

class Solution:

    def removeInvalidParentheses(self, s: str):

        ans = []

        path = []

        n = len(s)

        res_length = -1

        st = []

        def dfs(i):

            nonlocal res_length

            if i == n:

                if st == []: #栈空,有效字符串

                    if res_length == -1: #首次递归到的一定是最大长度的有效子集

                        res_length = len(''.join(path)) #更新最大长度

                    if len(''.join(path)) == res_length: #如果当前的path是最大长度,就加入答案

                        ans.append(''.join(path))

                return

#剪枝,n-i是没有选的长度+len(path)选择的长度 如果小于最大子集,就直接剪枝。

            if n - i + len(path) < res_length:

                return

            if s[i] not in '()': #字母直接加

                path.append(s[i])

                dfs(i+1)

                path.pop()

            else:

                path.append(s[i]) #先记录路径(先选,尽最大可能选)

                if s[i] == '(':

                    st.append(s[i]) #左括号入栈,然后递归

                    dfs(i+1)

                    st.pop() #恢复现场

                if s[i] == ')' and len(st) > 0: #右括号而且栈不是空

                    last = st.pop() #出栈,然后递归

                    dfs(i+1)

                    st.append(last) #恢复现场

                path.pop() #恢复现场

                dfs(i+1) #不选

        dfs(0)

        return list(set(ans))

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/654340.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL——视图(VIEW)详解

今天我们一起来学起视图(VIEW)&#xff0c;那么视图是什么呢&#xff1f;视图有什么作用呢&#xff1f;视图一方面可以帮我们使用表的一部分而不是所有的表&#xff0c;另一方面也可以针对不同的用户制定不同的查询视图&#xff01;带着问题一起来寻找答案吧~~~ 1. 常见的数据库…

【实验】语音识别

为学校数字信号处理实验总结和归纳&#xff1b; 语音识别 题目及相关要求在here. 数据预处理 大致步骤&#xff1a; 获取原始音频 检测 分帧 加窗 特征提取 端点检测 端点检测参数指标相对值初始短时能量高门限50初始短时能量低门限10初始短时过零率高门限10初始短时过零率低…

Web网页制作期末复习(1)——HTML5介绍、HTML5的DOCTYPE声明、HTML基本骨架、标题标签、段落 换行、水平线图片图片路径、超链接

目录 HTML5介绍 HTML5的DOCTYPE声明 HTML基本骨架 标题标签 段落、换行、水平线 图片 图片路径* 超链接 HTML5介绍 HTML5是用来描述网页的一种语言&#xff0c;被称为超文本标记语言。用HTML5编写的文件&#xff0c;后缀以.html结尾 HTML是一种标记语言&#xff0c;标…

在提交代码时有哪些注意事项

分享 10 种适合初学者的技术&#xff0c;这些技术将帮助您立即编写更好的代码。因此&#xff0c;如果您准备好将您的编码技能提升到一个新的水平&#xff0c;请继续阅读&#xff01; 1. 从计划开始 编写更好代码的最佳方法之一是从计划开始。在开始编码之前&#xff0c;请花几…

SQL详细处理流程.md

连接器&#xff1a;管理连接&#xff0c;权限验证解析器&#xff1a;词法以及语法分析优化器&#xff1a;生成执行计划&#xff0c;选择合适索引执行器&#xff1a;操作引擎获取结果存储引擎&#xff1a;存储数据&#xff0c;提供读写接口

iterm2 ssh免密码登录

不需要下载其他插件&#xff0c;使用脚本 目录 操作步骤如下&#xff1a; 实际举例如下&#xff1a; 1.编写sh文件 2.编辑sh文件 3.进入iterm2&#xff0c;打开profiles&#xff0c;edit profiles 4.验证 扩展 expect脚本 操作步骤如下&#xff1a; 在你电脑你想编辑的…

阿里云国际站:阿里云服务器安全性如何?有哪些安全措施和防护机制?

阿里云国际站&#xff1a;阿里云服务器安全性如何&#xff1f;有哪些安全措施和防护机制&#xff1f;   阿里云服务器安全性简介   作为全球领先的云计算服务提供商&#xff0c;阿里云始终注重保障用户数据安全。在面对各种网络攻击和安全威胁时&#xff0c;阿里云积极构建…

mysqldump 数据备份

使用实例 使用方法 Usage: mysqldump [OPTIONS] database [tables] OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3…] OR mysqldump [OPTIONS] --all-databases [OPTIONS] For more options, use mysqldump --help OPTION通常是&#xff1a;-u 用户名 -p …

【计算机网络自顶向下】计算机网络从0到1全篇总结-2023电子科技大学期末考试

相关术语 URI&#xff1a;Uniform Resource Identifier 统一资源标识符&#xff0c;指的是一个资源 URL&#xff1a;Uniform Resource Location 统一资源定位符&#xff0c;URI的子集&#xff0c;用地址定为的方式指定一个资源 URN&#xff1a;Uniform Resource Name 统一资…

基于微信小程序新疆特色产品团购系统设计与实现+第四稿+文档

博主介绍&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 项目名称 基于微信小程序新疆特色产品团购系统设计与实现第四稿文档 视频演示 视频去哪了呢&#xff1f;_哔哩哔哩_bilibili 系统介绍 2.3.1 主要功能描述 在…

常见技术场景

常见技术场景 1.单点登录这块怎么实现的 1.1 概述 单点登录的英文名叫做&#xff1a;Single Sign On&#xff08;简称SSO&#xff09;,只需要登录一次&#xff0c;就可以访问所有信任的应用系统 在以前的时候&#xff0c;一般我们就单系统&#xff0c;所有的功能都在同一个…

我准备蓝桥杯的这一年

我准备蓝桥杯的这一年 文章目录 我准备蓝桥杯的这一年起步和目标确定渐入佳境焦虑疲惫&#xff0c;一天又一天国赛我来力总结 我将我这段 流水账分为四个阶段。谨以此文&#xff0c;祭奠我这一年来的焦虑、白发~ &#xff0c;最终也取得了预期的成绩。不知未来再看此章会作何感…

hadoop基础

FileSystem使用 核心类 org.apache.hadoop.fs.FileSystem 文件系统类 抽象类 //静态方法创建对象 public static FileSystem newInstance(URI uri,Configuration conf,String user) /*参数一 URI 分布式文件系统 HDFS的资源地址 NN地址 hdfs://linux01:8020参数二 Configu…

Unity常见框架探索-ET框架探索

简介 ET框架是类ECS的一个Unity前后端框架 论坛地址为&#xff1a;https://et-framework.cn Git地址为&#xff1a;https://github.com/egametang/ET 预备知识 Unity程序集的使用 接入流程 本文将会以7.2版本进行分析。所以直接clone github上的仓库&#xff0c;将工程导…

1743_MATLAB 2-D绘图小结

全部学习汇总&#xff1a; GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes servral …

【网络协议详解】——知识点复习(期末不挂科版)

课本&#xff1a; 目录 &#x1f552; 1. 概述&#x1f558; 1.1 GNS3&#x1f558; 1.2 Wireshark &#x1f552; 2. PPP协议&#x1f552; 3. VLAN技术&#x1f552; 4. STP技术&#x1f552; 5. IPV6&#x1f552; 6. 路由表&#x1f552; 7. RIP协议&#x1f552; 8. OSPF…

Jenkins pipeline 中 checkout 代码

pipeline 中 具有checkout 功能的脚本命令如下 git branch: "master", url: "https://gitee.com/liuboliu/******.git"完整的脚本命令如下 pipeline {agent anystages {stage(checkout) {steps {git branch: "master", url: "https://gite…

I2C中为什么线与?为什么要有上拉电阻?

1、为什么采用漏极开路&#xff1f; 首先&#xff0c;连接到 I2C 上的设备是开漏输出的。以漏极开漏输出&#xff08;OD&#xff09;为例&#xff0c;是指将输出级电路结构改为一个漏极开路输出的 MOS 管。这样做的好处在于&#xff1a; 防止短路。可以实现“线与”逻辑&#…

移动DICT项目是什么?

DICT项目 我们运营商的伙伴&#xff0c;很多人都知道我们的DICT&#xff0c;但是大家知不知道什么是DICT。你想一想&#xff0c;所谓的DICT&#xff0c;就是指的大数据技术与IT和CT的深度融合。 实际上&#xff0c;DICT的可以拆分成三个词&#xff0c; 第一个DT&#xff0c…

腾讯服务器CentOS Stream 8安装redis详情的步骤

tencent服务器安装的系统版本创建一个新的文件夹 /athena/redis mkdir /athena cd /athena mkdir redis1、切换到 “redis” 目录&#xff1a; cd /athena/redis2、使用 YUM 包管理器安装 GCC、C 和 Make 软件包&#xff1a; yum install gcc-c make -y这条命令将使用 YUM …