码迷,mamicode.com
首页 > 其他好文 > 详细

301. Remove Invalid Parentheses

时间:2018-08-17 00:43:58      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:obs   change   insert   cte   public   because   strlen   one   red   

301. Remove Invalid Parentheses

https://leetcode.com/problems/remove-invalid-parentheses/discuss/75032/Share-my-Java-BFS-solution

Time complexity analysis 


// Input: "(a)())()"
// Output: ["(a)()()", "(a())()"]




// ********变种********
// 简单版:只输出第一个valid的  

// Time: O(n), 2 pass
// 思路:按照判断isValid的思路,只要遇到stack<0就remove,完了之后reverse再来一次。
public String removeInvalidParentheses(String s) {
  String r = remove(s, new char[]{‘(‘, ‘)‘});
  String tmp = remove(new StringBuilder(r).reverse().toString(), new char[]{‘)‘, ‘(‘});
  return new StringBuilder(tmp).reverse().toString();
}
private String remove(String s, char[] p) {
  int stack = 0;
  for (int i = 0; i < s.length(); i++) {
    if (s.charAt(i) == p[0])    stack++;
    if (s.charAt(i) == p[1])    stack--;
    if (stack < 0) {
      s = s.substring(0, i) + s.substring(i + 1);
      i--;
      stack = 0;
    }
  }
  return s;
}






  
  
  
我写的这个简单版还没测试过。。
public String remove(String s){
  String r = remove(s, new char[]{‘(‘, ‘)‘});
  
  String reverseR = new StringBuilder(r).reverse().toString();
  
  String tmp = remove(reverseR, new char[]{‘)‘,‘(‘});
  
  String result = new StringBuilder(tmp).reverse().toString();
  
  return result;
}

private String remove(String s, char[] p){
  int count = 0;
  for(int i = 0; i < s.length(); i++){
    char c = s.charAt(i);
    if(c != ‘(‘ && c != ‘)‘) continue;
    
    if(c == p[0]) count++;
    if(c == p[1]) count--;
    if(count == -1){
      s = s.substring(0, i) + s.substring(i + 1);
      // because we just delete a char, so index --
      i--;
      //and now the count is 0 
      count = 0;
    }
  }
  return s;
}
  



============





class Solution {
    public List<String> removeInvalidParentheses(String s) {
        List<String> result = new ArrayList<>();
        Queue<String> queue = new LinkedList<>();
        HashSet<String> visited = new HashSet<>();
        
        boolean found = false;
        
        queue.offer(s);
        visited.add(s);
        
        while(!queue.isEmpty()){
            String current = queue.poll();
            if(isValid(current)){
                result.add(current);
                found = true;
            }
            
            if(found) continue;
            
            //else , keep removing 
            for(int i = 0; i < current.length(); i++){
                char c = current.charAt(i);
                if(c != ‘(‘ && c != ‘)‘) continue;
                //else remove
                String newString  = current.substring(0, i) + current.substring(i + 1);
                if(!visited.contains(newString)){
                    visited.add(newString);
                    queue.offer(newString);
                }
            }
        }
        return result;

    
    }
    private boolean isValid(String input){
        int count = 0; 
        for(int i = 0; i < input.length(); i++){
            char c = input.charAt(i);
            if(c == ‘(‘){
                count++;
            }
            if(c == ‘)‘){
                count--;
            }
            if(count == -1){
                return false;
            }
        }
        return count == 0;
    }
}





==================


Observation:?if(found) continue; => This might add a shorter length string (max_len-1 to be precise) to the queue, but those will necessary be not valid so wont get added to the result. Reason: strlen needs to be even to be valid. strlen-1 will be odd and so never valid.

The case to visualize : Lets say string length is 7, so you can have 7 substrings of length 6 at level 1. Let‘s say first 4 were invalid, so they will be further chopped to length 5 and put on queue at level 2. Now you drain the queue once you find the valid case which is string 5 with len=6. None of those len=5 strings on queue can be valid as they are odd length.



 I would say the "if (found) continue;" did all the magic here to prevent outputing smaller size valid substrings like "()". The reason is just like jianchao said, number of valid parentheses should be even. By the time first valid output is collected, substrings differ in length of 2 has not been inserted yet.



class Solution {
    public List<String> removeInvalidParentheses(String s) {
      List<String> result = new ArrayList<>();
      if(s == null) return result;
      
      Set<String> visited = new HashSet<>();
      Queue<String> queue = new LinkedList<>();
      
      queue.offer(s);
      visited.add(s);
      
      boolean found = false;
      
      while(!queue.isEmpty()){
         // why String s  = queue.poll(); doesnt work ? 
    
        s = queue.poll();//String s  = queue.poll(); ??? 
          // if String s , then we have two Strings named after s 
          // when we say s, in this case , it just replaced s declared in 
          // the very above . 
          // i think we can use String current and change everythong below 
          // with current 
        
        if(isValid(s)){
          result.add(s);
          found = true;
        }
        
        if(found) continue;
          
          // what if among 1 2 3. 2 is the only valid newString. 
          //  1 is not valid, we remove each parentheses on 1 
          // add them to the queue. then we poll 2 from the queue
          // 2 is valid, so we dont remove parenthese on 2 anymore , same goes
          // for 3. so we add 2 to the result. and we should keep checking 3, 
          // 3 is invalid. after the first round, we should only output 2, but 
          // since we have some strings left from 1, if there is a valid one
          // we would add it to the result as well, since its added to the queue before 2 makes the boolean var found true. 
        
        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.offer(t);
            visited.add(t);
          }
        }
      }
      return result;
    }
  
    private 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--;
        if(count == -1) return false;
      }
      return count == 0;
    }
}

 

301. Remove Invalid Parentheses

标签:obs   change   insert   cte   public   because   strlen   one   red   

原文地址:https://www.cnblogs.com/tobeabetterpig/p/9490852.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!