1. 程式人生 > >#301 Remove Invalid Parentheses

#301 Remove Invalid Parentheses

Similar problem: #20 Valid Parentheses -- easy -- it only requires you to return true/false. We can simply use a stack to count whether the number of ( matches the number of ).

However, this question is harder than #20. We are required to return all possible valid strings without repeat in a List. This is a hard problem.

 

以下要點總結自#301的discussion板塊。

For example, if the case is ()), in order to avoid repeated results, we restrict ourselves to remove the first ) in a series of consecutive )s. After the removal, the prefix is then valid. We then call the function recursively to solve the rest of the string. However, we need to keep another information: the last removal position. If we do not have this position, we will generate duplicate by removing two ) in two steps only with a different order.

For this, we need to keep tracking the last removal position and only remove ) after that.

As for ((), we do the same thing from right to left. We can reverse the string and reuse the code.


參考程式碼:

public List<String> removeInvalidParentheses(String s) {
   List<String> ans = new ArrayList<>();
   remove(s, ans, 0, 0, new char[]{'(', ')'});
   return ans;
}

public void remove(String s, List<String> ans, int last_i, int last_j,  char[] par) {
   for (int stack = 0, i = last_i; i < s.length(); ++i) {

// valid checking...
       if (s.charAt(i) == par[0]) stack++;
       if (s.charAt(i) == par[1]) stack--;
       if (stack >= 0) continue;


// when the string is invalid...

       for (int j = last_j; j <= i; ++j){

// if it is ) for the first character, or it is the first )

// 在多一個)的情況下,拿掉前面任何一個)都可以
           if (s.charAt(j) == par[1] && (j == last_j || s.charAt(j - 1) != par[1])){
               remove(s.substring(0, j) + s.substring(j + 1, s.length()), ans, i, j, par);

}

       }
       return;
   }


   String reversed = new StringBuilder(s).reverse().toString();
   if (par[0] == '(') // finished left to right
       remove(reversed, ans, 0, 0, new char[]{')', '('});
   else // finished right to left
       ans.add(reversed);
}