1249
difficulty: Medium
Given a string s of '('
, ')'
and lowercase English characters.
Your task is to remove the minimum number of parentheses ( '('
or ')'
, in any positions ) so that the resulting parentheses string is valid and return any valid string.
Formally, a parentheses string is valid if and only if:
It is the empty string, contains only lowercase characters, or
It can be written as
AB
(A
concatenated withB
), whereA
andB
are valid strings, orIt can be written as
(A)
, whereA
is a valid string.
Example 1:
Input: s = "lee(t(c)o)de)"
Output: "lee(t(c)o)de"
Explanation: "lee(t(co)de)" , "lee(t(c)ode)" would also be accepted.
Example 2:
Input: s = "a)b(c)d"
Output: "ab(c)d"
Example 3:
Input: s = "))(("
Output: ""
Explanation: An empty string is also valid.
Example 4:
Input: s = "(a(b(c)d)"
Output: "a(b(c)d)"
Constraints:
1 <= s.length <= 10^5
s[i]
is one of'('
,')'
and lowercase English letters.
这个题要注意和301的区别。 301 要求的是所有的 minRemove 的结果 这个只需要找到其中的一个结果就好了。 区别在于,找到其中的一个结果,可以用好几种不同的算法。
Method One
class Solution {
public String minRemoveToMakeValid(String s) {
int netCount = 0;
LinkedList<Integer> indices = new LinkedList<>();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if( c == '(' ) {
indices.push(i);
netCount += 1;
}
if( c == ')' ) {
if( netCount > 0) {
netCount -= 1;
indices.pop();
}else {
indices.push(i);
}
}
}
StringBuilder ans = new StringBuilder();
Set<Integer> indicesSet = new HashSet<Integer>();
int sizeOfIndices = indices.size();
for( int i = 0; i < sizeOfIndices; i++ ) {
indicesSet.add(indices.pop());
}
for( int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(indicesSet.contains(i)) {
continue;
}
ans.append(c);
}
return String.valueOf(ans);
}
//不用以下的办法是因为 substring 是 O(N);
// public String removeIth(String s, int i) {
// return s.substring( 0 , i ) + s.substring( i + 1 );
// }
}
Method
以下是一个自己想的方法。原理大致相同。 这个题,O(N) 的解法,扫两遍数组是必须的。
class Solution {
public String minRemoveToMakeValid(String s) {
int counter = 0;
StringBuilder sb = new StringBuilder();
LinkedList<Integer> leftParenthesesIndices = new LinkedList<>();
int i = 0;
while( i < s.length() ){
if(s.charAt(i) == '('){
counter += 1;
leftParenthesesIndices.push(sb.length());
}
if(s.charAt(i) == ')'){
counter -= 1;
if( counter < 0){
i++;
counter = 0;
continue;
}
}
sb.append(s.charAt(i));
i++;
}
while( counter > 0 ){
sb.deleteCharAt(leftParenthesesIndices.pop());
counter--;
}
return sb.toString();
}
}
Method Best!
class Solution {
public String minRemoveToMakeValid(String s) {
// Parse 1: Remove all invalid ")"
StringBuilder sb = new StringBuilder();
int openSeen = 0;
int balance = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(') {
openSeen++;
balance++;
} if (c == ')') {
if (balance == 0) continue;
balance--;
}
sb.append(c);
}
// Parse 2: Remove the rightmost "("
StringBuilder result = new StringBuilder();
int openToKeep = openSeen - balance;
for (int i = 0; i < sb.length(); i++) {
char c = sb.charAt(i);
if (c == '(') {
openToKeep--;
if (openToKeep < 0) continue;
}
result.append(c);
}
return result.toString();
}
}
Last updated
Was this helpful?