Leetcode 31. 删除无效的括号

在这里插入图片描述

心路历程:

一开始看到有点懵,后来发现有点像按照一定规则穷举所有可能情况,想到了排列组合问题,再结合问题长度不固定,无法用已知个for循环表示,从而想到了回溯。这个题相当于需要在一定规则下枚举。
按照回溯的模板,递归循环是整个字符串s,for循环是候选集合。候选集合为第i个元素 “选” 或者 “不选” ,按照这个思路,其实就已经可以把所有可能组成的情况给遍历到,然后再从所有结果里搜集满足条件的即可。

这道题在回溯问题里很有代表性,考察了很多点,包括怎么对排列问题进行建模(选or不选)、如何判断满足括号条件(栈)、如何剪枝。一开始把问题想简单了,导致写完之后花了很长时间解决未通过的案例,这里面还是有一些细节需要考虑的,比如任何回溯都得在递归函数调用结束后“恢复现场”。

注意的点:

1、回溯算法在记录path时一定要记得copy
2、回溯函数中任何递归调用后都得恢复路径,比如这个问题里遇到字母时,虽然形成的树只有一个分支,但是返回后也得恢复path才行;当时第一次想这个问题以为单分支不用恢复路径导致de了半天bug。还是需要理解回溯是遍历边这个概念。
3、剪枝的判断直接返回就行,把剪枝的部分当作不需要记录path的终止条件即可。
4、每个节点候选集合都有空字符串和括号两个选择,需要遍历,没法贪婪地认为有括号选括号,因为需要考虑所有的组合。
5、注意题目中找的是删除最少括号后的所有可能组合,也就是最长的合法解,并且不能包含重复元素。

感悟:

1、算法题主要考察两类能力:一是对问题进行建模的能力;二是逻辑条件的想全能力。很多时候知道问题大概怎么做,但是具体想各种情况时还是会漏掉一些情况或者想错一些情况。
2、回溯问题debug可以从打印路径和候选集合的角度寻找错误。
3、很多算法中循环的建模思路都可以按照’选‘or’不选‘ 或者 ’选哪个‘的思路考虑,尤其在回溯、递归、动态规划等问题上,可以建模为决策问题。这一点其实和DRL在求解组合优化问题时的两类动作建模思路是一致的。

解法:

这道题有两个思路:思路一:剪枝+选择后序有可能形成最长路径;解法二:剪枝+找到所有的+判断满足条件的最长的。第二个可能更清晰,不过由于刚做完括号的题所以按照第一个思路写的AC解:

class Solution:def removeInvalidParentheses(self, s: str) -> List[str]:from collections import Counterpath = []res = []n = len(s)kuohaos = ['(', ')']mystack = Mystack()maxlen = 0def dfs(i):  # i代表遍历字符串的第i个元素# nonlocal s, n, res, path, mystack # 这一行可有可无nonlocal maxlen  # 这一行必须有# 剪枝:把一些不可能更长的去掉;if (n - len(path)) + len(''.join(path)) < maxlen:returnif i == n:string = ''.join(path.copy())maxlen = max(maxlen, len(string))res.append(string)returnif s[i] not in kuohaos:path.append(s[i])dfs(i+1)path.pop()  # 这块也得回溯!!!!!!!else:candidate = [""]# 看第i个括号能不能选即可if s[i] == '(':  # 后面)的数量大于等于栈长+1就可以选c = Counter(s[i+1:] + ')')  # +1防止为空# print(mystack.sk, c[')'], mystack.len())if c[')'] - 1 >= mystack.len() + 1: candidate.append("(")elif s[i] == ')':  # 栈里有左括号if mystack.len() > 0:candidate.append(')')else:assert False, s[i]for each in candidate:# print(each, path, i)path.append(each)  # path 怎么会这么长?# 维护一下栈if each != "":mystack.append(each)dfs(i+1)path.pop()if each != "":mystack.pop(each)dfs(0)# 返回res里最长的lengths = [len(eve) for eve in res]res = [eve for eve in res if len(eve) == max(lengths)]return list(set(res))  # 需要去重class Mystack:def __init__(self):from collections import dequeself.sk = deque()def pop(self, ele):if ele == '(':self.sk.pop()elif ele == ')':self.sk.append('(')else:assert False, eledef append(self, ele):if ele == '(':self.sk.append('(')elif ele == ')':assert len(self.sk) != 0self.sk.pop()else:assert False, eledef len(self):return len(self.sk)

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

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

相关文章

力扣题目训练(22)

2024年2月15日力扣题目训练 2024年2月15日力扣题目训练563. 二叉树的坡度637. 二叉树的层平均值643. 子数组最大平均数 I304. 二维区域和检索 - 矩阵不可变154. 寻找旋转排序数组中的最小值 II 2024年2月15日力扣题目训练 2024年2月15日第二十二天编程训练&#xff0c;今天主要…

3月17日ACwing每日一题

1230. K倍区间 - AcWing题库 //超时写法 需要优化 //两个1e5嵌套 变成1e10了>1e8需要优化 #include <bits/stdc.h> using namespace std; const int N100007; int a[N]; int main(){int n,k;cin>>n>>k;for(int i1;i<n;i){cin>>a[i];a[i]a[i-1]…

web ui自动化测试--元素操作

一、介绍 什么是web ui自动化测试 1、通过代码来模拟人的手工操作,执行测试内容 2、自动化是为了代替重复的手工操作,提高测试效率 ui自动化的价值: 1、回归速度的对比,以前进行全量回归测试需要x天,现在有没有减少 2、负责功能测试的同事,是不是有更多的时间测试新需求…

Java面试题总结15之简述你对RPC,RMI的理解

RPC&#xff1a;在本地调用远程的函数&#xff0c;远程过程调用&#xff0c;可以跨语言实现&#xff0c;httpClient RMI&#xff1a;远程方法调用&#xff0c;Java中用于实现RPC的一种机制&#xff0c;RPC的Java版本是J2EE的网络调用机制&#xff0c;跨JVM调用对象的方法&…

Redis-2 Redis基础数据类型与基本使用

高级Redis应用进阶 一站式Redis解决方案-Redis-2 Redis基础数据类型与基本使用 源代码在GitHub - 629y/food-social-contact-parent: redis项目-美食社交APP 1. Redis基本数据类型 1.字符串&#xff08;strings&#xff09; set username zhangsan get username mset age 18 …

JAVA代理模式梳理

什么是代理模式 代理模式&#xff1a;为其他对象提供一种代理&#xff0c;用以控制对这个对象的访问&#xff1b; 我们使用代理对象&#xff0c;可以在不修改目标对象的基础上&#xff0c;增强主业务逻辑&#xff1b;比如说我们的系统中有一个登录接口&#xff0c;我们要对这个…

在数据对象中增加新的属性值,数据更新,视图不更新问题

一、原始数据 dataTable:[{aa:111} ]然后我需要再给他一个对象属性值&#xff0c;就会发现打印出来的数据是更新了&#xff0c;视图不更新&#xff0c;原因是在于在Vue实例创建时&#xff0c; dataTable.bb 并未声明&#xff0c;因此就没有被Vue转换为响应式的属性. this.dat…

ECMAscript6学习

ECMAscript6介绍 ECMA是一个浏览器脚本标准制定的公司&#xff0c;Netscape 创造了 JavaScript 由于商标原因&#xff0c; 后面ECMA公司取名ECMAscript 1 发布&#xff0c;JavaScript 也就是 ECMAscript.到现在最新的版本是6&#xff0c;简称es6. 新增let 与const let 与const …

【数据分析可视化】动态生成柱状图

import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as ticker from matplotlib.animation import FuncAnimation import matplotlib.patches as mpatches from matplotlib.animation import FFMpegWriter# 定义一个函数&#xff0c;用于生成…

探秘酒店业黑科技:3D可视化引领管理新风尚

在信息化飞速发展的今天&#xff0c;酒店管理已不再是传统的模式所能满足。 想象一下&#xff0c;你站在一个巨大的3D地图上&#xff0c;轻轻一点&#xff0c;就能瞬间进入酒店的任何一个角落。你可以看到客房的布置、餐厅的摆设、会议室的布局……一切都如同身临其境&#xff…

shell编程中 for while until循环的使用方法及案例

CSDN 成就一亿技术人&#xff01; 作者主页&#xff1a;点击&#xff01; Shell编程专栏&#xff1a;点击&#xff01; CSDN 成就一亿技术人 ————前言———— Shell脚本编程中&#xff0c;有几种常见的循环结构&#xff0c;包括for循环、while循环和until循环&#xf…

C goto 语句

C 语言中的 goto 语句允许把控制无条件转移到同一函数内的被标记的语句。 注意&#xff1a;在任何编程语言中&#xff0c;都不建议使用 goto 语句。因为它使得程序的控制流难以跟踪&#xff0c;使程序难以理解和难以修改。任何使用 goto 语句的程序可以改写成不需要使用 goto 语…

PWM驱动舵机

PWM驱动舵机 接线图 程序结构图&#xff1a; pwm.c部分代码 #include "stm32f10x.h" // Device headervoid PWM_Init(void){// 开启时钟&#xff0c;这里TIM2是通用寄存器RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);// GPIO初始化代…

MATLAB中的脚本和函数有什么区别?

MATLAB中的脚本和函数是两种不同的代码组织方式&#xff0c;它们在结构、功能和使用方式上有显著的区别。以下是对这两种方式的详细解释&#xff0c;总计约2000字。 一、MATLAB脚本 MATLAB脚本是一种包含多条MATLAB命令的文件&#xff0c;这些命令按照在文件中的顺序依次执行…

2.27线性模型

可以利用无监督学习解决的问题&#xff0c;大致分为两类&#xff1a; 关联分析&#xff1a;发现不同事物之间同时出现的概率。在购物篮分析中被广泛地应用。如果发现买面包的客户有百分之八十的概率买鸡蛋&#xff0c;那么商家就会把鸡蛋和面包放在相邻的货架上。 聚类问题&a…

Java的集合类

一、集合&#xff08;Collection和Map&#xff09; &#xff08;一&#xff09;List集合&#xff08;有序&#xff0c;可重复&#xff0c;存取顺序一致&#xff09;&#xff1a; 1.概述&#xff1a; 有序的collection&#xff0c;此接口的用户可以对列表中每个元素的插入位置…

onnx 格式模型可视化工具

onnx 格式模型可视化工具 0. 引言1. 可视化工具2. 安装 Netron: Viewer for ONNX models 0. 引言 ONNX 是一种开放格式&#xff0c;用于表示机器学习模型。ONNX 定义了一组通用运算符&#xff08;机器学习和深度学习模型的构建基块&#xff09;和通用文件格式&#xff0c;使 A…

100天精通Python(实用脚本篇)——第118天:基于selenium和ddddocr库实现反反爬策略之验证码识别

文章目录 专栏导读一、前言二、ddddocr库使用说明1. 介绍2. 算法步骤3. 安装4. 参数说明5. 纯数字验证码识别6. 纯英文验证码识别7. 英文数字验证码识别8. 带干扰的验证码识别 三、验证码识别登录代码实战1. 输入账号密码2. 下载验证码3. 识别验证码并登录 书籍推荐 专栏导读 …

SAR ADC教程系列5——FFT频谱泄露以及相干采样

频谱泄露的出现以及如何规避&#xff1f; 为什么要相干采样&#xff1f; 1.分析ADC输出信号的频谱工具&#xff1a;DFT&#xff08;Discrete Fourier Transform) 重点&#xff1a;DFT相邻频谱频率间隔为fs/N 如何规避频谱泄露&#xff1f; 对于DFT&#xff0c;它对于接收到的信…

前端项目部署后,如何提示用户版本更新

目录 前言解决方案1、public目录下新建manifest.json2、写入当前时间戳到manifest.json3、检查版本更新4、woker线程5、入口文件引入 可能出现的问题 前言 项目部署上线后&#xff0c;特别是网页项目&#xff0c;提示正在操作系统的用户去更新版本非常 important。一般我们都会…