当前位置: 首页 > ds >正文

力扣301:删除无效的括号

力扣301:删除无效的括号

  • 题目
  • 思路
  • 代码

题目

给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。

返回所有可能的结果。答案可以按 任意顺序 返回。

思路

看到任意顺序所以先想回溯。
想到回溯先想回溯的结束条件是什么:字符串是否是有效的也就是字符串里的括号能否全部匹配成功。所以我们需要设计一个返回值为bool类型的函数判断字符串是否有效,具体实现也好想既然是判断括号是否能否匹配上我们只需要定义一个整型total,遇到左括号就++遇到右括号就–,然后再判断total是否小于0如果小于就说明右括号的数量大于左括号了直接返回false。等循环结束后再判断total是否为0为0就返回true不为零就返回false。
回溯的结束条件讲完了接下来就是如何进行回溯,我们先仔细观察题目。题目上说要删除最小的无效括号所以我们没法随意的删除我们必须先计算出要删除多少个左括号和右括号才能在数量上匹配也就是左括号和右括号的数量是相同的。怎么计算呢?我们定义两个遍历一个左括号的数量leftcount一个右括号的数量rightcount,然后我们遍历字符串遇到左括号就对leftcount++,遇到右括号的时候我们先判断左括号的数量leftcount是否大于零如果大于零说明这一对括号可以匹配上所以要对leftcount进行–。如果小于0说明这个右括号是多余的也就要对rightcount进行++。在一轮遍历后我们就得到了要删除的左括号和右括号数量。在得到了要删除的左括号和右括号的数量后我们就可以开始回溯了,回溯的本体也很简单只要遇到左括号并且leftcount大于0我们就尝试删除左括号,右括号同理。
在回溯的大概流程讲完后就是其中的一些特殊情况,第一回溯结束的判断条件不止是字符串是否有效还有一个条件就是剩下的字符串数量要大于要删除的括号数量也就是leftcount+rightcount。这个道理很简单剩下的字符串全删了都没法完成左右括号数量上的匹配那就可以直接不用玩了。还有一个细节是剪枝方面的,我们要返回的是所以可能的结果所以可能有重复的情况出现,那么什么情况下会有重复呢?多个相同的括号堆在一起也就是连续好几个左括号或者右括号所以我们就需要进行剪枝也就是判断当前位置的符号是否和上一个位置的符号相同,如果相同就直接下一轮。这样就避免了重复答案的出现。

代码

class Solution {
public:vector<string> res;bool IsVaild(string tmp) {int total = 0;for (auto ch : tmp) {if (ch == '(') {total++;} else if (ch == ')') {total--;}if (total < 0) {return false;}}return total == 0;}void dfs(string s, int start, int leftcount, int rightcount) {// 回溯的结束条件:字符串是否是有效的if (IsVaild(s)) {res.push_back(s);return;}for (int i = start; i < s.size(); i++) {// 如果要删除的字符串数量已经大于剩下的字符数就直接返回if (leftcount + rightcount > s.size() - i) {return;}// 进行剪枝:去除那些连续的括号避免生成重复的字符串if (i != start && s[i] == s[i - 1]) {continue;}// 去除一个左括号if (leftcount > 0 && s[i] == '(') {dfs(s.substr(0, i) + s.substr(i + 1), i, leftcount - 1,rightcount);}// 去除一个右括号if (rightcount > 0 && s[i] == ')') {dfs(s.substr(0, i) + s.substr(i + 1), i, leftcount,rightcount - 1);}}}vector<string> removeInvalidParentheses(string s) {// 需要删除的左括号和右括号数量int leftcount = 0;int rightcount = 0;// 先计算出需要删减出多少个括号// 才能在数量上完成匹配for (auto ch : s) {if (ch == '(') {leftcount++;} else if (ch == ')') {// 如果还有左括号那么这两个括号就可以进行匹配也就不用删除了if (leftcount > 0) {leftcount--;} else {rightcount++;}}}// 然后通过回溯来完成删除工作dfs(s, 0, leftcount, rightcount);return res;}
};
http://www.xdnf.cn/news/17159.html

相关文章:

  • iostat 系统IO监控命令学习
  • AR技术赋能轨道交通培训:虚实结合提升学习效率
  • Kotlin Daemon 简介
  • 从零开始搞定类与对象(中)
  • AI 面试 vs 真人面试:破解企业招聘效率困局
  • 【STM32】GPIO的输入输出
  • 数据结构(2)
  • SpringBoot3.0+Vue3.0开源版考试系统
  • ubuntu22.04系统实践 linux基础入门命令(三) 用户管理命令
  • 抗辐照DCDC与MCU在核环境监测设备中的集成应用
  • Jwts用于创建和验证 ​​JSON Web Token(JWT)​​ 的开源库详解
  • 【MATLAB例程】水下AUV自主导航定位例程,定位使用TDOA(到达时间差),适用于三维环境,附代码下载链接
  • MySQL详解
  • ICCV 2025|单视频生成动态4D场景!中科大微软突破4D生成瓶颈,动画效果炸裂来袭!
  • Linux下载安装mysql,客户端(Navicat)连接Linux中的mysql
  • 消防器材检测数据集介绍-9,600 张图片 智慧安防系统 建筑施工安全监管 AI 消防巡检机器人 自动审核系统 公共场所安全监测
  • 【核心技术二】Uvicorn:高性能 ASGI 服务器
  • React Hooks 原理深度解析与最佳实践
  • 在CentOS 7上安装配置MySQL 8.0完整指南
  • JVM-垃圾回收器与内存分配策略详解
  • 模拟-6.N字形变换-力扣(LeetCode)
  • 基于springboot的学习辅导系统设计与实现
  • 【深度学习新浪潮】谷歌新推出的AlphaEarth是款什么产品?
  • spring-ai-alibaba 之 graph 槽点
  • 若没有安全可靠性保障,对于工程应用而言,AI或许就是大玩具吗?
  • 嵌入式通信协议解析(基于红外NEC通信协议)
  • 深入解析C++函数重载:从原理到实践
  • 模型学习系列之参数
  • C# LINQ(LINQ to XML)
  • OpenWrt | 如何在 ucode 脚本中打印日志