【LeetCode】301.删除无效的括号

题目

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

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

示例 1:

复制代码
输入:s = "()())()"
输出:["(())()","()()()"]

示例 2:

复制代码
输入:s = "(a)())()"
输出:["(a())()","(a)()()"]

示例 3:

复制代码
输入:s = ")("
输出:[""]

提示:

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

解答

源代码

java 复制代码
class Solution {
    List<String> res;

    public List<String> removeInvalidParentheses(String s) {
        res = new ArrayList<>();
        int lremove = 0, rremove = 0;

        for (char c : s.toCharArray()) {
            if (c == '(') {
                lremove++;
            } else if (c == ')') {
                if (lremove > 0) {
                    lremove--;
                } else {
                    rremove++;
                }
            }
        }

        func(s, 0, lremove, rremove);

        return res;
    }

    public void func(String str, int start, int lremove, int rremove) {
        // 没有需要去掉的左右括号了
        if (lremove == 0 && rremove == 0) {
            if (isValid(str)) {
                res.add(str);
            }

            return;
        }

        for (int i = start; i < str.length(); i++) {
            if (i != start && str.charAt(i) == str.charAt(i  - 1)) {
                continue;
            }

            // 剩余的字符数量小于需要去掉的括号数,那就不符合,直接返回
            if (lremove + rremove > str.length() - i) {
                return;
            }

            if (lremove > 0 && str.charAt(i) == '(') {
                func(str.substring(0, i) + str.substring(i + 1), i, lremove - 1, rremove);
            }

            if (rremove > 0 && str.charAt(i) == ')') {
                func(str.substring(0, i) + str.substring(i + 1), i, lremove, rremove - 1);
            }
        }
    }

    public boolean isValid(String str) {
        int count = 0;

        for (char c : str.toCharArray()) {
            if (c == '(') {
                count++;
            } else if (c == ')') {
                count--;

                if (count < 0) {
                    return false;
                }
            }
        }

        return count == 0;
    }
}

总结

我们可以使用回溯算法,尝试遍历所有可能的去掉非法括号的方案。

先对原字符串进行统计,得到需要去掉的左右括号数量。然后我们尝试在原字符串中去掉这些数量的左右括号,检测剩余的字符串是否合法匹配,如果合法匹配则我们则认为该字符串为可能的结果,我们利用回溯算法来尝试搜索所有可能的去除括号的方案。

当需要去掉的左右括号的数量都为0时,判断此时的字符串是否匹配,若匹配则记录下来。

剩余字符数量小于当前左右括号数量时,可以直接判断字符串不符合,返回。

为了避免得到重复的结果,我们在每次进行搜索时,如果遇到连续相同的括号我们只需要搜索一次即可,比如当前遇到的字符串为 "(((())",去掉前四个左括号中的任意一个,生成的字符串是一样的,均为 "((())",因此我们在尝试搜索时,只需去掉一个左括号进行下一轮搜索,不需要将前四个左括号都尝试一遍。

相关推荐
Albert Edison4 分钟前
【RabbitMQ】七种工作模式
java·开发语言·分布式·rabbitmq
橘颂TA5 分钟前
【笔试】算法的暴力美学——牛客 NC242:单词搜索,思路:dfs 算法
算法·深度优先
小旭95278 分钟前
SpringBoot 项目实战:ECharts 数据可视化 + POI Excel 报表导出完整版教程
java·spring boot·后端·信息可视化·echarts
程序员老邢10 分钟前
【技术底稿 13】内网 Milvus 2.3.0 向量数据库全流程部署(商助慧 AI 底座,Attu 可视化)
java·数据库·人工智能·ai·语言模型·milvus
YXWik612 分钟前
Langchain4j(5)RAG之多格式文档加载(PDF / Word / TXT / 批量文件夹)
java
Seven9712 分钟前
【从0到1构建一个ClaudeAgent】内存管理-上下文压缩
java
迷藏49416 分钟前
**基于Python与OpenCV的光场显示图像处理技术实践**在现代显示技术发展中,**光场显示(Light
java·图像处理·python·opencv
沐苏瑶20 分钟前
Java据结构深度解析:AVL 树与红黑树
数据结构·算法
Godson_beginner21 分钟前
Aspose.PDF for Java(实现PDF转Word无水印无页数限制)
java·spring·pdf·文档转换
feifeigo12321 分钟前
MATLAB中对转子建立有限元模型并进行动力学计算
算法