Leetcode 31. 删除无效的括号

news2024/10/7 8:01:13

在这里插入图片描述

心路历程:

一开始看到有点懵,后来发现有点像按照一定规则穷举所有可能情况,想到了排列组合问题,再结合问题长度不固定,无法用已知个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 Counter
        path = []
        res = []
        n = len(s)
        kuohaos = ['(', ')']
        mystack = Mystack()
        maxlen = 0

        def dfs(i):  # i代表遍历字符串的第i个元素
            # nonlocal s, n, res, path, mystack # 这一行可有可无
            nonlocal maxlen  # 这一行必须有

            # 剪枝:把一些不可能更长的去掉;
            if (n - len(path)) + len(''.join(path)) < maxlen:
                return
           
            if i == n:
                string = ''.join(path.copy())
                maxlen = max(maxlen, len(string))
                res.append(string)
                return
            
            if 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 deque
        self.sk = deque()
    
    def pop(self, ele):
        if ele == '(':
            self.sk.pop()
        elif ele == ')':
            self.sk.append('(')
        else:
            assert False, ele
    
    def append(self, ele):
        if ele == '(':
            self.sk.append('(')
        elif ele == ')':
            assert len(self.sk) != 0
            self.sk.pop()
        else:
            assert False, ele

    def len(self):
        return len(self.sk)

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

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

相关文章

第2章 进程与线程(3)

2.3 同步与互斥 引入同步的原因是【进程的并发具有异步性,以各自独立不可预知的速度推进】 2.3.1 同步与互斥的基本概念 1.临界资源:一次仅仅允许一个进程所使用的资源叫做临界资源。 2.同步:进程同步是确保多个进程在共享资源的访问过程中按照一定规则进行协调和管理的过程。…

STM32CubeIDE基础学习-BEEP蜂鸣器实验

STM32CubeIDE基础学习-BEEP蜂鸣器实验 文章目录 STM32CubeIDE基础学习-BEEP蜂鸣器实验前言第1章 硬件介绍第2章 工程配置2.1 工程外设配置部分2.2 生成工程代码部分 第3章 代码编写第4章 实验现象总结 前言 前面学习了LED闪烁实验&#xff0c;现在来学习一下蜂鸣器发声实验&am…

Stable Diffusion出图时,一次性比较多个lora的效果?

事前准备 在WebUI中&#xff0c;lora插件&#xff08;也算是模型&#xff09;的存放位置为&#xff1a; 你的WebUI启动器根目录\models\Lora 把训练好的&#xff0c;或者下载到的模型放到这个文件夹。 重启WebUI之后就会出现在这里 在Lora标签中 注意&#xff1a;这些lora需要…

前端接口防止重复请求实现方案

虽然大部分的接口处理我们都是加了loading的&#xff0c;但又不能确保真的是每个接口都加了的&#xff0c;可是如果要一个接口一个接口的排查&#xff0c;那这维护了四五年的系统&#xff0c;成百上千的接口肯定要耗费非常多的精力&#xff0c;根本就是不现实的&#xff0c;所以…

springboot基于JAVA的邮件过滤系统设计与实现

摘 要 当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;人类的生存和思考方式也产生了变化。传统邮件过滤、意见反馈采取了人工的管理方法&#xff0c;但这种管理方法存在着许多弊端&#xff0c;比如效率低下、安全性低以及信息传输的不准确等&#xff…

【剑指offer--C/C++】JZ25 合并两个排序的链表

题目 思路 这个题目大逻辑比较简单&#xff0c;就是一个比较和穿插&#xff0c;但细节上要考虑清楚&#xff0c;可以画个图模拟一下。我这里是设置将两个链表拆开组成一个新的链表&#xff0c;这样不需要占用新的空间。两个指针对应节点的值进行比较&#xff0c;那个节点值较小…

【2024第一期CANN训练营】3、AscendCL运行时管理

文章目录 【2024第一期CANN训练营】3、AscendCL运行时管理1. 初始化与去初始化2. 资源申请与释放2.1 申请流程2.2 释放流程2.3 运行模式&#xff08;可选&#xff09; 3. 数据传输3.1 接口调用流程3.2 主要数据传输场景1. Host内的数据传输2. 从Host到Device的数据传输3. 从Dev…

【深度学习】滴滴出行-交通场景目标检测

案例5&#xff1a;滴滴出行-交通场景目标检测 相关知识点&#xff1a;目标检测、开源框架的配置和使用&#xff08;mmdetection, mmcv&#xff09; 1 任务目标 1.1 任务和数据简介 本次案例将使用深度学习技术来完成城市交通场景下的目标检测任务&#xff0c;案例所使用的数…

「全栈」低代码时代开启!页面开发、数据处理、复杂逻辑统统一站搞定!

数字化浪潮的推进让企业对应用开发效率有着愈发严苛的要求。 传统的开发模式&#xff0c;无论是前端开发还是后端处理&#xff0c;都普遍面临周期长、成本高、响应慢、迭代难等问题&#xff0c;由于部分企业长期未进行创新改革&#xff0c;导致每次在新增系统功能时&#xff0…

【源码阅读】Mybatis底层源码分析(详细Debug查看附代码)

一、搭建测试代码框架 &#xff08;代码已提交到github->测试代码&#xff0c;建议结合代码根据本文debug一遍更有利于理解&#xff0c;帮忙点个Star 哈&#xff0c;本人在这里谢谢了&#xff09; 二、猜想Mybatis是如何设计的 从上面的案例中&#xff0c;可以大致可以猜测…

VMware虚拟机硬盘容量扩容方法

扩容后不会影响原文件。亲测有效&#xff0c;高效便捷 - 在关机状态下&#xff0c;先在VM上直接扩容硬盘容量&#xff0c;输入扩容后的硬盘最大容量 注意&#xff0c;如果想在原硬盘上增加容量&#xff0c;需要将原来的快照都删除 - 输入最大磁盘大小 运行虚拟机进入系统&…

【代码】伪标签图像随机生成

这段代码将生成2-4个大小不同的圆形和1-2个大小不同的椭圆形&#xff0c;并确保它们之间以及与背景边界之间不会发生重叠 限制圆形的半径不超过150&#xff0c;第13行 import cv2 import random import os这段代码将生成2-4个大小不同的圆形和1-2个大小不同的椭圆形&#xff0…

代码随想录算法训练营第八天|344.反转字符串、541. 反转字符串II、卡码网:54.替换数字、151.翻转字符串里的单词、卡码网:55.右旋转字符串

题目&#xff1a;344.反转字符串 文章链接&#xff1a;代码随想录 视频链接&#xff1a;LeetCode:344.反转字符串 题目链接&#xff1a;力扣题目链接 图释&#xff1a; // 反转字符串 void reverseString(vector<char>& s) {// 直接使用反转的库函数 reverserev…

数字化转型之于国家:为三驾马车更新马达

随着国民经济和社会发展第十四个五年规划的开启&#xff0c;中国也进入了全面建设社会主义现代化国家的新发 展阶段&#xff0c;未来要在坚持“创新、协调、绿色、开放、共享”的新发展理念下&#xff0c;在质量效益明显提升的基础上实 现经济持续健康发展。持续的发展意味着…

水库大坝安全监测中需要注意的事项

随着经济和社会的发展&#xff0c;水资源的需求也在不断增加。因此&#xff0c;建设水库已成为保障水资源的主要方式之一。然而&#xff0c;随着水库规模的增大和工程的复杂性的增加&#xff0c;水库大坝的安全问题也日益引起重视。为此&#xff0c;需要对水库大坝进行安全监测…

【爬虫】– 抓取原创力文档数据

使用RPA工具&#xff0c;实现针对于原创力中不可下载文档的抓取&#xff0c;可延用于其他类似文库 1 使用工具、环境 影刀RPA、WPS Office、谷歌浏览器&#xff08;非指定&#xff09; 2 代码流程 3 关键点 此方案只适合抓取非VIP即可预览全文的文档&#xff0c;抓取下来的数…

计算机网络 谢希仁(001-1)

计算机网络-方老师 总时长 24:45:00 共50个视频&#xff0c;6个模块 此文章包含1.1到1.4的内容 简介 1.1计算机网络的作用 三网融合&#xff08;三网合一&#xff09; 模拟信号就是连续信号 数字信号是离散信号 1.2互联网概述 以前2兆带宽就要98 现在几百兆带宽也就几百块 …

海川润泽AI机器视觉仪系列产品,助推“人工智能+”打开新质生产力的大门

3月5日&#xff0c;第十四届全国人民代表大会第二次会议开幕。国务院总理李强在政府工作报告&#xff0c;提出大力推进现代化产业体系建设&#xff0c;加快发展新质生产力。深入推进数字经济创新发展&#xff0c;制定支持数字经济高质量发展政策&#xff0c;积极推进数字产业化…

AI+权重衰退

AI权重衰退 1权重衰退2代码实现 2丢弃法 1权重衰退 AI权重衰退是指在人工智能&#xff08;AI&#xff09;领域中的一种技术或方法&#xff0c;用于训练机器学习模型时对权重进行惩罚或调整&#xff0c;以避免过拟合现象的发生。 在机器学习中&#xff0c;过拟合是指模型在训练…

Debug追踪

2.2 Debug追踪 使用IDEA的断点调试功能&#xff0c;查看程序的运行过程 在有效代码行&#xff0c;点击行号右边的空白区域&#xff0c;设置断点&#xff0c;程序执行到断点将停止&#xff0c;我们可以手动来运行程序 点击Debug运行模式 程序停止在断点上不再执行&#xff0c…