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

【LeetCode每日一题】——301.删除无效的括号

文章目录

  • 一【题目类别】
  • 二【题目难度】
  • 三【题目编号】
  • 四【题目描述】
  • 五【题目示例】
  • 六【题目提示】
  • 七【解题思路】
  • 八【时间频度】
  • 九【代码实现】
  • 十【提交结果】

一【题目类别】

  • 广度优先搜索

二【题目难度】

  • 困难

三【题目编号】

  • 301.删除无效的括号

四【题目描述】

  • 给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。
  • 返回所有可能的结果。答案可以按 任意顺序 返回。

五【题目示例】

  • 示例 1:

    • 输入:s = "()())()"
    • 输出:["(())()","()()()"]
  • 示例 2:

    • 输入:s = "(a)())()"
    • 输出:["(a())()","(a)()()"]
  • 示例 3:

    • 输入:s = ")("
    • 输出:[""]

六【题目提示】

  • 1 <= s.length <= 25
  • s 由小写英文字母以及括号 '('')' 组成
  • s 中至多含 20 个括号

七【解题思路】

  • 这道题我觉得还是挺难的,虽然没用到什么特别的算法,不过很难想到(我个人感觉)
  • 要解决这道题我们首先要考虑使用什么方法,我们仔细阅读题目后发现一个细节,即删除最少数量的无效括号以达到目的
  • 既然要最少数量,我们想是不是可以每次删除一个括号,然后下一次以每次删除后的结果继续向下删除括号以测试现在的括号是否有效呢?
  • 这个思路显然是可以的,并且由于每次只删除一个括号,所以显然满足题目要求的最少次数,而且自然的想到了广度优先搜索:
    • 队列中初始化为输入字符串
    • 然后进入广度优先遍历算法
    • 每次首先判断当前得到的字符串中是否存在满足要求的括号序列(写一个函数判断,这个很简单)
      • 如果存在满足要求的括号序列,直接返回结果即可
      • 如果不存在满足要求的括号序列,就在上次处理的结果上,继续逐个删除括号,在下一层继续判断是否存在满足要求的括号序列
    • 最后返回结果即可
  • 具体细节可以参考下面的代码

八【时间频度】

  • 时间复杂度: O ( n × 2 n ) O(n \times 2^n) O(n×2n) n n n为字符串的长度
  • 空间复杂度: O ( n × C n n 2 ) O(n \times C_{n}^{\frac{n}{2}}) O(n×Cn2n) n n n为字符串的长度

九【代码实现】

  1. Java语言版
class Solution {public List<String> removeInvalidParentheses(String s) {// 存储结果List<String> res = new ArrayList<String>();// 存储当前层字符串的集合(去重)Set<String> curLevel = new HashSet<String>();curLevel.add(s);// 使用广度优先遍历算法删除无效的括号while (true) {// 查看当前层字符串的集合是否存在满足要求的字符串序列for (String str : curLevel) {if (isValid(str)) {res.add(str);}}// 若找到满足要求的字符串序列,直接返回if (res.size() > 0) {return res;}// 存储下一层字符串的集合(去重)Set<String> nextLevel = new HashSet<String>();// 根据上一层的结果计算下一层的字符序列for (String str : curLevel) {for (int i = 0; i < str.length(); i++) {// 避免重复计算if (i > 0 && str.charAt(i) == str.charAt(i - 1)) {continue;}// 每个位置的括号都要删除一次if (str.charAt(i) == '(' || str.charAt(i) == ')') {nextLevel.add(str.substring(0, i) + str.substring(i + 1, str.length()));}}}// 开始以下一层为基准进行下一批次的遍历curLevel = nextLevel;}}// 判断给定的括号序列是否有效private boolean isValid(String str) {char[] strs = str.toCharArray();int count = 0;for (char s : strs) {if (s == '(') {count++;} else if (s == ')') {count--;if (count < 0 ) {return false;}}}return count == 0;}}
  1. Python语言版
class Solution:def removeInvalidParentheses(self, s: str) -> List[str]:# 判断给定的括号序列是否有效def isValid(string):count = 0for s in string:if s == "(":count += 1elif s == ")":count -= 1if count < 0:return Falsereturn count == 0# 存储结果res = []# 存储当前层字符串的集合(去重)cur_level = set([s])# 使用广度优先遍历算法删除无效的括号while True:# 查看当前层字符串的集合是否存在满足要求的字符串序列for string in cur_level:if isValid(string):res.append(string)# 若找到满足要求的字符串序列,直接返回if len(res) > 0:return res# 存储下一层字符串的集合(去重)next_level = set()# 根据上一层的结果计算下一层的字符序列for string in cur_level:for i in range(len(string)):# 避免重复计算if i > 0 and string[i] == s[i - 1]:continue# 每个位置的括号都要删除一次if string[i] == "(" or string[i] == ")":next_level.add(string[:i] + string[i + 1:])# 开始以下一层为基准进行下一批次的遍历cur_level = next_level# 返回结果return res
  1. C++语言版
class Solution {
public:// 判断给定的括号序列是否有效bool isValid(string str) {int count = 0;for (char s : str) {if (s == '(') {count++;} else if (s == ')') {count--;if (count < 0) {return false;}}}return count == 0;}vector<string> removeInvalidParentheses(string s) {// 存储结果vector<string> res;// 存储当前层字符串的集合(去重)unordered_set<string> curLevel;curLevel.insert(s);// 使用广度优先遍历算法删除无效的括号while(true) {// 查看当前层字符串的集合是否存在满足要求的字符串序列for (auto & str : curLevel) {if (isValid(str)) {res.emplace_back(str);}}// 找到满足要求的字符串序列,直接返回if (res.size() > 0) {return res;}// 存储下一层字符串的集合(去重)unordered_set<string> nextLevel;// 根据上一层的结果计算下一层的字符序列for (auto & str : curLevel) {for(int i = 0; i < str.size(); i++) {// 避免重复计算if(i > 0 && str[i] == str[i - 1]) {continue;}// 每个位置的括号都要删除一次if (str[i] == '(' || str[i] == ')') {nextLevel.insert(str.substr(0, i) + str.substr(i + 1, str.size()));}}}// 开始以下一层为基准进行下一批次的遍历curLevel = nextLevel;}// 返回结果return res;}
};

十【提交结果】

  1. Java语言版
    在这里插入图片描述

  2. Python语言版
    在这里插入图片描述

  3. C++语言版
    在这里插入图片描述


http://www.mrgr.cn/news/2394.html

相关文章:

  • 并查集(路径压缩、按秩合并、按大小合并)
  • 嵌入式ubuntu忘记root密码修改方法
  • 编写开放接口与思考
  • 每天一个数据分析题(四百八十三)- 统计推断
  • 【STM32 FreeRTOS】软件定时器
  • Django后端架构开发:从匿名用户API节流到REST自定义认证
  • 实现将docx转成PDF
  • HTML+CSS+JS实现商城首页[web课设代码+模块说明+效果图]
  • 单片机学习笔记概述
  • 全国10米分辨率逐年植被覆盖度(FVC)数据集
  • 860.柠檬水找零
  • C#收集海康系读码器内容并硬触发IO报警
  • Linux软件编程-day(14) 多路连接方法
  • Windows 上设置 MySQL 的主从复制
  • go语言递归、分解处理任务
  • Crypto++:私钥和公钥保存到文件
  • Linux外设接口使用及内核驱动开发---Ubuntu搭建Linux内核开发环境
  • swift微调款框架使用自定义数据集进行通义千问1.5的微调
  • ClickHouse集群的安装
  • 插值算法在数学建模中的应用:以淡水养殖池塘数据为例