Last active
May 28, 2025 22:28
-
-
Save GopinathMR/59bb0d13111b1833780dd66b046bbe46 to your computer and use it in GitHub Desktop.
Leetcode 1249 variant which should also cover different paranthesis types and matching should be based on the paranthesis type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// leet code 1249 variant | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Stack; | |
import org.apache.commons.lang3.tuple.Pair; | |
import com.google.common.collect.BiMap; | |
import com.google.common.collect.HashBiMap; | |
import com.google.common.collect.Ordering; | |
public class Solution { | |
/** | |
* 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. | |
* | |
* @param s input string containing parentheses and lowercase English characters | |
* @return valid string with minimum parentheses removed | |
*/ | |
public String minRemoveToMakeValid(String s) { | |
BiMap<Character, Character> openCloseMap = HashBiMap.create(); | |
openCloseMap.put('(', ')'); | |
openCloseMap.put('[', ']'); | |
openCloseMap.put('{', '}'); | |
BiMap<Character, Character> closeOpenMap = openCloseMap.inverse(); | |
Map<Character, Integer> openCountMap = new HashMap<>(); | |
openCountMap.put('(', 0); | |
openCountMap.put('[', 0); | |
openCountMap.put('{', 0); | |
Stack<Pair<Character, Integer>> stack = new Stack<>(); | |
List<Integer> indicesToBeRemoved = new ArrayList<>(); | |
int index = 0; | |
for (char c : s.toCharArray()) { | |
if (openCloseMap.containsKey(c)) { | |
//open paranthesis | |
Pair<Character, Integer> entry = Pair.of(c, index); | |
stack.push(entry); | |
openCountMap.put(c, openCountMap.get(c) + 1); | |
} else if (openCloseMap.containsValue(c)) { | |
// close paranthesis | |
Character open = closeOpenMap.get(c); | |
int count = openCountMap.get(open); | |
if (count == 0) { | |
indicesToBeRemoved.add(index); | |
} else { | |
removeFromStack(stack, open, indicesToBeRemoved, openCountMap); | |
} | |
} | |
index++; | |
} | |
emptyStack(stack, indicesToBeRemoved); | |
indicesToBeRemoved.sort(Ordering.natural()); | |
char[] array = s.toCharArray(); | |
StringBuilder builder = new StringBuilder(); | |
for (int i = 0; i < array.length; i++) { | |
if (indicesToBeRemoved.size() > 0 && i == indicesToBeRemoved.get(0)) { | |
// skip it | |
indicesToBeRemoved.remove(0); | |
} else { | |
builder.append(array[i]); | |
} | |
} | |
return builder.toString(); | |
} | |
private void removeFromStack(Stack<Pair<Character, Integer>> stack, Character open, List<Integer> indiciesToBeRemoved, Map<Character, Integer> openCountMap) { | |
while (stack.size() > 0) { | |
Pair<Character, Integer> entry = stack.pop(); | |
openCountMap.put(entry.getLeft(), openCountMap.get(entry.getLeft()) - 1); | |
if (entry.getLeft() == open) { | |
break; | |
} else { | |
indiciesToBeRemoved.add(entry.getRight()); | |
} | |
} | |
} | |
private void emptyStack(Stack<Pair<Character, Integer>> stack, List<Integer> indiciesToBeRemoved) { | |
for (int index = 0; index < stack.size(); ++index) { | |
Pair<Character, Integer> entry = stack.get(index); | |
indiciesToBeRemoved.add(entry.getRight()); | |
} | |
} | |
public static void main(String[] args) { | |
Solution solution = new Solution(); | |
// Test cases | |
String[] testCases = { | |
"lee(t(c)o)de)", // Expected: "lee(t(c)o)de" | |
"a)b(c)d", // Expected: "ab(c)d" | |
"))((", // Expected: "" | |
"(a(b(c)d)", // Expected: "a(b(c)d)" | |
"a)b(c)d", // Expected: "ab(c)d" | |
"({([{]}}))" // Expected: "({[]})". This is the most complicated testcase to pass through where open/close should match paranthesis type too. | |
}; | |
String[] expectedOutputs = { | |
"lee(t(c)o)de", | |
"ab(c)d", | |
"", | |
"a(b(c)d)", | |
"ab(c)d", | |
"({[]})" | |
}; | |
for (int i = 0; i < testCases.length; i++) { | |
String result = solution.minRemoveToMakeValid(testCases[i]); | |
System.out.printf("Test case %d:%n", i + 1); | |
System.out.printf("Input: %s%n", testCases[i]); | |
System.out.printf("Expected: %s%n", expectedOutputs[i]); | |
System.out.printf("Actual: %s%n", result); | |
System.out.printf("Test %s%n%n", | |
result.equals(expectedOutputs[i]) ? "PASSED" : "FAILED"); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment