301. Remove Invalid Parentheses

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())()"]
")(" -> [""]

摘自:https://discuss.leetcode.com/topic/28827/share-my-java-bfs-solution

The idea is straightforward, with the input string s, we generate all possible states by removing one ( or ), check if they are valid, if found valid ones on the current level, put them to the final result list and we are done, otherwise, add them to a queue and carry on to the next level.

The good thing of using BFS is that we can guarantee the number of parentheses that need to be removed is minimal, also no recursion call is needed in BFS.

Thanks to @peisi, we don't need stack to check valid parentheses.

Time complexity:

In BFS we handle the states level by level, in the worst case, we need to handle all the levels, we can analyze the time complexity level by level and add them up to get the final complexity.

On the first level, there's only one string which is the input string s, let's say the length of it is n, to check whether it's valid, we needO(n) time. On the second level, we remove one ( or ) from the first level, so there are C(n, n-1) new strings, each of them hasn-1 characters, and for each string, we need to check whether it's valid or not, thus the total time complexity on this level is (n-1) xC(n, n-1). Come to the third level, total time complexity is (n-2) x C(n, n-2), so on and so forth...

Finally we have this formula:

T(n) = n x C(n, n) + (n-1) x C(n, n-1) + ... + 1 x C(n, 1) = n x 2^(n-1).


层次依次为删除0个元素,1个元素,2个元素。。。(和原串对照),对每层只遍历删除一个字符的情况。

层次遍历所有的可能。如果有一种可能是valid,就剪枝不再遍历下面的层。

public List<String> removeInvalidParentheses(String s) {
	      List<String> res = new ArrayList<>();
	      
	      if (s == null) return res;
	      
	      Set<String> visited = new HashSet<>();
	      Queue<String> queue = new LinkedList<>();
	      
	      queue.add(s);
	      visited.add(s);
	      
	      boolean found = false;
	      
	      while (!queue.isEmpty()) 
	      {
	        s = queue.poll();
	        
	        if (isValid(s))
	        {
	          res.add(s);
	          found = true;
	        }
	      
	        if (found) continue;
	      
	        for (int i = 0; i < s.length(); i++) 
	        {
	    
	          if (s.charAt(i) != '(' && s.charAt(i) != ')')
	            continue;
	          String t = s.substring(0, i) + s.substring(i + 1);
	        
	          if (!visited.contains(t)) 
	          {
	           
	            queue.add(t);
	            visited.add(t);
	          }
	        }
	      }
	      
	      return res;
	    }
	    
	   
	    boolean isValid(String s) 
	    {
	      int count = 0;
	    
	      for (int i = 0; i < s.length(); i++) 
	      {
	        char c = s.charAt(i);
	        if (c == '(') count++;
	        if (c == ')' && count-- == 0) return false;
	      }
	      return count == 0;
	    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值