题目原文:
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的,更慢且不易理解。