关闭

Hard-题目9:301. Remove Invalid Parentheses

93人阅读 评论(0) 收藏 举报
分类:

题目原文:
Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.

Note: The input string may contain letters other than the parentheses ( and ).

Examples:
“()())()” -> [“()()()”, “(())()”]
“(a)())()” -> [“(a)()()”, “(a())()”]
“)(” -> [“”]
题目大意:
给出一个括号和字母的字符串,其中有一些括号是失配的,求出所有去掉失配括号的解。
例如:
“()())()” -> [“()()()”, “(())()”]
(这个例子中多了一个右括号,但有两种去掉右括号的方式,故最后答案有2个解)
题目分析:
参考别人博客的解法,使用DFS求解。
首先定义“失配度”,代表字符串或其子串中失配括号的个数,博客中给出的解法大多使用了堆栈,其实不用,只用一个整形(相当于堆栈长度)维护即可,遇到左括号+1,遇到右括号如果长度不为0则减1,否则失配度+1,扫完字符串后加上这个长度(失配左括号数)。
然后从源字符串开始搜索,遍历字符串,如果当前字符串不是括号则跳过,否则计算去掉这个括号的失配度,如果比当前失配度小1,则继续向下搜索这个子串(说明继续寻找可以找到解),如果比当前失配度大1,则说明去掉这个括号不能得到解(因为继续搜索下去即使找到解也去掉了原来已经匹配的括号!),如果失配度=0则找到解。
这里需要用一个HashSet记录所有搜索过的字符串,如果一个字符串已经搜索过则不再搜索。这是个很重要的剪枝,否则会超时。因为对”((((((((((((((((((((((((((())”这个串,如果不做这个处理,第一层就会对每个去掉左括号的子串搜索一遍,而它们是一样的,可想而知有多少重复操作!
源码:(language:java)

public class Solution {
    HashSet<String> visited = new HashSet<String>();
    private int getMisses(String s) { // calculate the missing num of parentheses
        int parentheses = 0;
        int miss = 0;
        for(int i = 0;i<s.length();i++) {
            if(s.charAt(i) == '(')
                parentheses++;
            else if(s.charAt(i) == ')'){
                if(parentheses==0) 
                    miss++;
                else
                    parentheses--;
            }
        }
        miss+=parentheses;
        return miss;
    }
    private void dfs(List<String> list, String s, int miss) {
        if(miss == 0) 
            list.add(s);
        else {
            for(int i = 0;i<s.length();i++) {
                String nextStr = removeCharAt(s, i); 
                if(!visited.contains(nextStr)) {
                    visited.add(nextStr);
                    int nextMiss = getMisses(nextStr);
                    if(nextMiss<miss)
                        dfs(list, nextStr, nextMiss);
                }
            }
        }
    }
    private String removeCharAt(String s, int pos) {
          return s.substring(0, pos) + s.substring(pos + 1);
    }

    public List<String> removeInvalidParentheses(String s) {
        List<String> list = new ArrayList<String>();
        dfs(list,s,getMisses(s));
        return list;

    }
}

成绩:
23ms,beats 57.67%,众数3ms,13.37%
Cmershen的碎碎念:
3ms的办法也用到了递归,但不知道有没有回溯,在discuss https://leetcode.com/discuss/81478/easy-short-concise-and-fast-java-dfs-3-ms-solution中有介绍,但满篇E文让我懒得看,而博客中的中文分析大多与上述解法类似(我也是基于中文博客做的),还有一种基于bfs的,更慢且不易理解。

0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:55414次
    • 积分:3192
    • 等级:
    • 排名:第10658名
    • 原创:270篇
    • 转载:53篇
    • 译文:0篇
    • 评论:7条
    文章分类
    最新评论