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

news2024/9/23 9:28:59

文章目录

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

一【题目类别】

  • 广度优先搜索

二【题目难度】

  • 困难

三【题目编号】

  • 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 = 0
            for s in string:
                if s == "(":
                    count += 1
                elif s == ")":
                    count -= 1
                    if count < 0:
                        return False
            return 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.coloradmin.cn/o/2057325.html

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

相关文章

C++ 内存布局 - Part4: 多继承与this指针调整

1. 多继承代码 #include <iostream> #include <cstdio> using namespace std;class Base1 { public:virtual void fooA() { cout << "Base1::fooA" << endl; }virtual void fooB() { cout << "Base1::fooB" << endl;…

叉车ai行人防撞预警系统,前后盲区防撞报警,让行车更安全!

标准配件&#xff1a;主机前/后/内置3个镜头喇叭电源线保险丝摄像头固定支架&#xff08;含螺丝&#xff09;天线主机固定胶条 九盾叉车ai行人防撞预警系统功能主要透过三颗独立摄像头&#xff0c;结合深度学习算法以完成机器视觉的识别工作。其中两颗具备补光设计的超广角摄像…

文本匹配任务(上)

文本匹配任务 1.文本匹配介绍1.1文本匹配定义1.1.1狭义定义1.1.2广义定义 1.2文本匹配应用1.2.1问答对话1.2.1信息检索 2.文本匹配--智能问答2.1基本思路2.2技术路线分类2.2.1按基础资源划分2.2.2 答案生成方式2.2.3 NLP技术 2.3智能问答-Faq知识库问答2.3.1运行逻辑2.3.2核心关…

DC-DC FB分压电阻计算 (MP1584 SY8205为例)

【本文发布于https://blog.csdn.net/Stack_/article/details/141371702&#xff0c;未经许可不得转载&#xff0c;转载须注明出处】 获取文件 【MP1584 MP2451 SY8205 SY8201 FB分压电阻计算】 一般DC-DC芯片对输出电压的调节&#xff0c;是以FB引脚达到0.6V或者0.8V为止的&…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第六篇 嵌入式GUI开发篇-第八十五章 Qt控制硬件

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

【Java 数据结构】排序

排序 排序排序是什么排序相关概念稳定性比较排序非比较排序内部排序外部排序 常见比较排序冒泡排序基本思想代码实现 选择排序基本思想代码实现 插入排序基本思想代码实现 希尔排序基本思想代码实现 堆排序基本思想代码实现 快速排序基本思想代码实现优化其他实现寻找基准非递归…

如何使⽤组将⼀个文件拆分成多个文件 (LINQ)(C#)

文章目录 一、背景二、实现步骤三、完整示例四、总结 在日常开发过程中&#xff0c;我们可能会遇到需要将一个大型文件拆分成多个小文件的需求。例如&#xff0c;为了便于传输、处理或备份&#xff0c;我们可以将一个大的日志文件拆分成多个小文件。在C#中&#xff0c;我们可以…

Spring模块详解Ⅱ

目录 Spring Beans模块详解1. 什么是 Bean?2. Spring Bean的配置方式2.1 基于 XML 配置例子&#xff1a; 2.2 基于注解配置例子&#xff1a; 2.3 基于 Java 配置&#xff08;JavaConfig&#xff09;例子&#xff1a; 3. Bean 的生命周期生命周期回调的例子&#xff1a; 4. Bea…

数据采集-->kafka-->hdfs

数据采集到kafka flume: a1.sources r1 a1.channels c1a1.sources.r1.type TAILDIR a1.sources.r1.filegroups f1 a1.sources.r1.filegroups.f1 /opt/installs/flume1.9/job/a.log a1.sources.r1.positionFile /opt/installs/flume1.9/job/taildir-kafka.jsona1.channe…

react antd TreeSelect实现自定义标签

<ProFormTreeSelectlabel"接收对象"name"receiverObjects"colProps{{ span: 16 }}labelCol{{span: 6,}}wrapperCol{{span: 18,}}rules{[{ required: true }]}fieldProps{{showSearch: true,multiple: true,// autoClearSearchValue: true,filterTreeNod…

《通义千问AI落地—中》:前端实现

一、前言 本文源自微博客且已获授权,请尊重版权. 书接上文&#xff0c;上文中&#xff0c;我们介绍了通义千问AI落地的后端接口。那么&#xff0c;接下来我们将继续介绍前端如何调用接口以及最后的效果&#xff1b;首先看效果&#xff1a; 上述就是落地到本微博客以后的页面效果…

三角形最小路径和[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个三角形triangle&#xff0c;找出自顶向下的最小路径和。 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 1 的两个结点。也就是说&#xff0c;如果…

代码随想录 day 49 单调栈

第十章 单调栈part02 42. 接雨水 接雨水这道题目是 面试中特别高频的一道题&#xff0c;也是单调栈 应用的题目&#xff0c;大家好好做做。 建议是掌握 双指针 和单调栈&#xff0c;因为在面试中 写出单调栈可能 有点难度&#xff0c;但双指针思路更直接一些。 在时间紧张的情…

深入探讨 Nginx:安装、配置及优化指南

一、Nginx 概述及编译安装 1、概述 Nginx是一个高性能的开源HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/POP3邮件代理服务器。它最初由Igor Sysoev于2002年开发&#xff0c;并于2004年首次发布。Nginx以其高并发性、低资源消耗和灵活的配置能力而受到广泛关注&#x…

卡码网KamaCoder 105. 有向图的完全可达性

题目来源&#xff1a;105. 有向图的完全可达性 C题解1&#xff1a; #include <iostream> #include <vector> #include <algorithm>using namespace std;int main(){int N, K;cin>>N>>K;// 如果边的数量不够&#xff0c;则一定不能到达所有点if…

使用Harbor搭建Docker私有仓库

一、harbor&#xff1a;开源的企业级的docker仓库软件&#xff0c;仓库就是保持镜像的。 1.仓库分两种&#xff1a;私有仓库&#xff1a;运维用的最多 公有仓库 2.harbor是有图形化的&#xff0c;页面UI展示的一个工具&#xff0c;操作直观 3.注意点&#xff1a;harbor都是由…

拖拽式报表设计器优点好 实现流程化办公就靠它!

当前&#xff0c;实现流程化办公是很多企业都想要实现的目标。利用低代码技术平台、拖拽式报表设计器的优势特点&#xff0c;可以为企业降低开发成本、提升办公效率、创造更多市场价值。那么&#xff0c;您知道拖拽式报表设计器的优点是什么吗&#xff1f;通过本文一起了解拖拽…

疫情期间我面试了13家企业软件测试岗位,一些面试题整理

项目的测试流程 拿到需求文档后&#xff0c;写测试用例 审核测试用例 等待开发包 部署测试环境 冒烟测试&#xff08;网页架构图&#xff09; 页面初始化测试&#xff08;查看数据库中的数据内容和页面展示的内容是否一致&#xff0c;并且是否按照某些顺序排列&#xff09…

JavaScript_9_练习:随机点名

效果图 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>练习&#xff1a;随机点名</title&g…

C语言中的预处理详解

1. 预定义符号 C语⾔设置了⼀些预定义符号&#xff0c;可以直接使⽤&#xff0c;预定义符号也是在预处理期间处理的。 举个例⼦&#xff1a; printf("file:%s line:%d\n", __FILE__, __LINE__); 2. #define 定义常量 基本语法&#xff1a; #define name stuff 举个例…