【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语言版
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语言版
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++语言版
cpp 复制代码
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++语言版

相关推荐
hope_wisdom13 分钟前
Python面试宝典第49题:字符串压缩
python·算法·面试·笔试题·字符串压缩·双指针法·使用栈
MATLAB代码顾问27 分钟前
如何用MATLAB计算多边形的几何中心
算法·机器学习·matlab
栩日月29 分钟前
Linux学习记录十四----------线程的创建和回收
linux·数据结构·学习
戊子仲秋31 分钟前
【LeetCode】每日一题 2024_9_13 预算内的最多机器人数目(滑动窗口、单调队列)
算法·leetcode
CV金科38 分钟前
蓝桥杯-STM32G431RBT6(UART解析字符串sscanf和解决串口BUG)
c语言·stm32·单片机·嵌入式硬件·mcu·算法·bug
机器学习之心1 小时前
顶刊算法 | 鹈鹕算法POA-Transformer-LSTM多变量回归预测
算法·lstm·transformer·多变量回归预测·poa
WenGyyyL1 小时前
面试经典150题——多数元素
算法·哈希表·摩尔算法
i嗑盐の小F1 小时前
【 ACM独立出版,见刊后1个月检索!!!】第二届通信网络与机器学习国际学术会议(CNML 2024,10月25-27)
网络·图像处理·人工智能·深度学习·算法·机器学习·计算机视觉
oliveira-time1 小时前
C++ prime plus课后习题-第二章
开发语言·c++·算法
Chase-Hart2 小时前
【每日一题】LeetCode 7.整数反转(数学)
java·数据结构·算法·leetcode·eclipse